[Metrics UI] Observability Overview Host Summary (#90879)

* [Metrics UI] Observability Overview Host Summary

* Adding UI elements

* Adding logos

* Changing the size of the request

* Change to new ECS fields for network traffic

* Adding logos to HostLink component

* Round seconds

* fixing data handler test

* Fixing test for metrics_overview_fetchers

* Adding types for SVG to observability

* Adding i18n support to table labels

* removing unused translations

* move back to host.network.(in,out).bytes

* Adding changes to source from #95334

* Fixing source type

* Removing unintentional change.

* Maybe, fixing types

* removing svg typings

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Chris Cowan 2021-04-06 08:38:12 -07:00 committed by GitHub
parent 70b3b2bbc1
commit 91b727f412
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 2512 additions and 319 deletions

View file

@ -34,6 +34,53 @@ export const OverviewRequestRT = rt.type({
}),
});
export const TopNodesRequestRT = rt.intersection([
rt.type({
sourceId: rt.string,
size: rt.number,
bucketSize: rt.string,
timerange: rt.type({
from: rt.number,
to: rt.number,
}),
}),
rt.partial({ sort: rt.string, sortDirection: rt.string }),
]);
export type TopNodesRequest = rt.TypeOf<typeof TopNodesRequestRT>;
const numberOrNullRT = rt.union([rt.number, rt.null]);
const stringOrNullRT = rt.union([rt.string, rt.null]);
export const TopNodesTimeseriesRowRT = rt.type({
timestamp: rt.number,
cpu: numberOrNullRT,
iowait: numberOrNullRT,
load: numberOrNullRT,
rx: numberOrNullRT,
tx: numberOrNullRT,
});
export const TopNodesSeriesRT = rt.type({
id: rt.string,
name: stringOrNullRT,
platform: stringOrNullRT,
provider: stringOrNullRT,
cpu: numberOrNullRT,
iowait: numberOrNullRT,
load: numberOrNullRT,
uptime: numberOrNullRT,
rx: numberOrNullRT,
tx: numberOrNullRT,
timeseries: rt.array(TopNodesTimeseriesRowRT),
});
export const TopNodesResponseRT = rt.type({
series: rt.array(TopNodesSeriesRT),
});
export type TopNodesResponse = rt.TypeOf<typeof TopNodesResponseRT>;
export type OverviewMetricType = rt.TypeOf<typeof OverviewMetricTypeRT>;
export type OverviewMetric = rt.TypeOf<typeof OverviewMetricRT>;
export type OverviewResponse = rt.TypeOf<typeof OverviewResponseRT>;

View file

@ -3,19 +3,7 @@
exports[`Metrics UI Observability Homepage Functions createMetricsFetchData() should just work 1`] = `
Object {
"appLink": "/app/metrics/inventory?waffleTime=(currentTime:1593696311629,isAutoReloading:!f)",
"stats": Object {
"cpu": Object {
"type": "percent",
"value": 0.10691011235955057,
},
"hosts": Object {
"type": "number",
"value": 1,
},
"memory": Object {
"type": "percent",
"value": 0.5389775280898876,
},
},
"series": Array [],
"sort": [Function],
}
`;

View file

@ -174,7 +174,7 @@ export const AlertPreview: React.FC<Props> = (props) => {
title={
<PreviewTextString
previewResult={previewResult}
hasWarningThreshold={hasWarningThreshold}
hasWarningThreshold={Boolean(hasWarningThreshold)}
/>
}
>

View file

@ -69,9 +69,11 @@ describe('Metrics UI Observability Homepage Functions', () => {
bucketSize,
});
expect(core.http.post).toHaveBeenCalledTimes(1);
expect(core.http.post).toHaveBeenCalledWith('/api/metrics/overview', {
expect(core.http.post).toHaveBeenCalledWith('/api/metrics/overview/top', {
body: JSON.stringify({
sourceId: 'default',
bucketSize,
size: 5,
timerange: {
from: startTime.valueOf(),
to: endTime.valueOf(),

View file

@ -5,8 +5,16 @@
* 2.0.
*/
/*
* Copyright
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { FetchDataParams, MetricsFetchDataResponse } from '../../observability/public';
import { OverviewRequest, OverviewResponse } from '../common/http_api/overview_api';
import { TopNodesRequest, TopNodesResponse } from '../common/http_api/overview_api';
import { InfraClientCoreSetup } from './types';
export const createMetricsHasData = (
@ -20,38 +28,33 @@ export const createMetricsHasData = (
export const createMetricsFetchData = (
getStartServices: InfraClientCoreSetup['getStartServices']
) => async ({ absoluteTime }: FetchDataParams): Promise<MetricsFetchDataResponse> => {
) => async ({ absoluteTime, bucketSize }: FetchDataParams): Promise<MetricsFetchDataResponse> => {
const [coreServices] = await getStartServices();
const { http } = coreServices;
const { start, end } = absoluteTime;
const makeRequest = async (overrides: Partial<TopNodesRequest> = {}) => {
const { start, end } = absoluteTime;
const overviewRequest: OverviewRequest = {
sourceId: 'default',
timerange: {
from: start,
to: end,
},
const overviewRequest: TopNodesRequest = {
sourceId: 'default',
bucketSize,
size: 5,
timerange: {
from: start,
to: end,
},
...overrides,
};
const results = await http.post<TopNodesResponse>('/api/metrics/overview/top', {
body: JSON.stringify(overviewRequest),
});
return {
appLink: `/app/metrics/inventory?waffleTime=(currentTime:${end},isAutoReloading:!f)`,
series: results.series,
sort: async (by: string, direction: string) =>
makeRequest({ sort: by, sortDirection: direction }),
};
};
const results = await http.post<OverviewResponse>('/api/metrics/overview', {
body: JSON.stringify(overviewRequest),
});
return {
appLink: `/app/metrics/inventory?waffleTime=(currentTime:${end},isAutoReloading:!f)`,
stats: {
hosts: {
type: 'number',
value: results.stats.hosts.value,
},
cpu: {
type: 'percent',
value: results.stats.cpu.value,
},
memory: {
type: 'percent',
value: results.stats.memory.value,
},
},
};
return await makeRequest();
};

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import { TopNodesResponse } from '../../common/http_api/overview_api';
export const FAKE_SNAPSHOT_RESPONSE = {
nodes: [
{
@ -309,10 +311,6 @@ export const FAKE_SNAPSHOT_RESPONSE = {
interval: '300s',
};
export const FAKE_OVERVIEW_RESPONSE = {
stats: {
hosts: { type: 'number', value: 1 },
cpu: { type: 'percent', value: 0.10691011235955057 },
memory: { type: 'percent', value: 0.5389775280898876 },
},
export const FAKE_OVERVIEW_RESPONSE: TopNodesResponse = {
series: [],
};

View file

@ -4,25 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import Boom from '@hapi/boom';
import { schema } from '@kbn/config-schema';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { findInventoryFields } from '../../../common/inventory_models';
import { throwErrors } from '../../../common/runtime_types';
import { OverviewRequestRT } from '../../../common/http_api/overview_api';
import { createValidationFunction } from '../../../common/runtime_types';
import { TopNodesRequestRT } from '../../../common/http_api/overview_api';
import { InfraBackendLibs } from '../../lib/infra_types';
import { createSearchClient } from '../../lib/create_search_client';
const escapeHatch = schema.object({}, { unknowns: 'allow' });
interface OverviewESAggResponse {
memory: { value: number };
hosts: { value: number };
cpu: { value: number };
}
import { queryTopNodes } from './lib/get_top_nodes';
export const initOverviewRoute = (libs: InfraBackendLibs) => {
const { framework } = libs;
@ -30,76 +16,23 @@ export const initOverviewRoute = (libs: InfraBackendLibs) => {
framework.registerRoute(
{
method: 'post',
path: '/api/metrics/overview',
path: '/api/metrics/overview/top',
validate: {
body: escapeHatch,
body: createValidationFunction(TopNodesRequestRT),
},
},
async (requestContext, request, response) => {
const overviewRequest = pipe(
OverviewRequestRT.decode(request.body),
fold(throwErrors(Boom.badRequest), identity)
);
const options = request.body;
const client = createSearchClient(requestContext, framework);
const source = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client,
overviewRequest.sourceId
options.sourceId
);
const inventoryModelFields = findInventoryFields('host', source.configuration.fields);
const params = {
index: source.configuration.metricAlias,
body: {
query: {
range: {
[source.configuration.fields.timestamp]: {
gte: overviewRequest.timerange.from,
lte: overviewRequest.timerange.to,
format: 'epoch_millis',
},
},
},
aggs: {
hosts: {
cardinality: {
field: inventoryModelFields.id,
},
},
cpu: {
avg: {
field: 'system.cpu.total.norm.pct',
},
},
memory: {
avg: {
field: 'system.memory.actual.used.pct',
},
},
},
},
};
const esResponse = await client<{}, OverviewESAggResponse>(params);
const topNResponse = await queryTopNodes(options, client, source);
return response.ok({
body: {
stats: {
hosts: {
type: 'number',
value: esResponse.aggregations?.hosts.value ?? 0,
},
cpu: {
type: 'percent',
value: esResponse.aggregations?.cpu.value ?? 0,
},
memory: {
type: 'percent',
value: esResponse.aggregations?.memory.value ?? 0,
},
},
},
body: topNResponse,
});
}
);

View file

@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { TopNodesResponse } from '../../../../common/http_api/overview_api';
import { InfraDatabaseSearchResponse } from '../../../lib/adapters/framework';
import { getMetadataFromNodeBucket } from './get_matadata_from_node_bucket';
import { ESResponseForTopNodes } from './types';
export const convertESResponseToTopNodesResponse = (
response: InfraDatabaseSearchResponse<{}, ESResponseForTopNodes>
): TopNodesResponse => {
if (!response.aggregations) {
return { series: [] };
}
return {
series: response.aggregations.nodes.buckets.map((node) => {
return {
id: node.key,
...getMetadataFromNodeBucket(node),
timeseries: node.timeseries.buckets.map((bucket) => {
return {
timestamp: bucket.key,
cpu: bucket.cpu.value,
iowait: bucket.iowait.value,
load: bucket.load.value,
rx: bucket.rx.value,
tx: bucket.tx.value,
};
}),
cpu: node.cpu.value,
iowait: node.iowait.value,
load: node.load.value,
uptime: node.uptime.value,
rx: node.rx.value,
tx: node.tx.value,
};
}),
};
};

View file

@ -0,0 +1,127 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { MetricsSourceConfiguration } from '../../../../common/metrics_sources';
import { TopNodesRequest } from '../../../../common/http_api/overview_api';
export const createTopNodesQuery = (
options: TopNodesRequest,
source: MetricsSourceConfiguration
) => {
const sortByHost = options.sort && options.sort === 'name';
const sortField = sortByHost ? '_key' : options.sort ?? 'uptime';
const sortDirection = options.sortDirection ?? 'asc';
return {
size: 0,
query: {
bool: {
filter: [
{
range: {
[source.configuration.fields.timestamp]: {
gte: options.timerange.from,
lte: options.timerange.to,
},
},
},
{
match_phrase: { 'event.module': 'system' },
},
],
},
},
aggs: {
nodes: {
terms: {
field: 'host.name',
size: options.size,
order: { [sortField]: sortDirection },
},
aggs: {
metadata: {
top_metrics: {
metrics: [
{ field: 'host.os.platform' },
{ field: 'host.name' },
{ field: 'cloud.provider' },
],
sort: { '@timestamp': 'desc' },
size: 1,
},
},
uptime: {
max: {
field: 'system.uptime.duration.ms',
},
},
cpu: {
avg: {
field: 'system.cpu.total.pct',
},
},
iowait: {
avg: {
field: 'system.core.iowait.pct',
},
},
load: {
avg: {
field: 'system.load.15',
},
},
rx: {
sum: {
field: 'host.network.in.bytes',
},
},
tx: {
sum: {
field: 'host.network.out.bytes',
},
},
timeseries: {
date_histogram: {
field: '@timestamp',
fixed_interval: '1m',
extended_bounds: {
min: options.timerange.from,
max: options.timerange.to,
},
},
aggs: {
cpu: {
avg: {
field: 'host.cpu.pct',
},
},
iowait: {
avg: {
field: 'system.core.iowait.pct',
},
},
load: {
avg: {
field: 'system.load.15',
},
},
rx: {
rate: {
field: 'host.network.ingress.bytes',
},
},
tx: {
rate: {
field: 'host.network.egress.bytes',
},
},
},
},
},
},
},
};
};

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { NodeBucket } from './types';
interface Metadata {
name: string | null;
provider: string | null;
platform: string | null;
}
export const getMetadataFromNodeBucket = (node: NodeBucket): Metadata => {
const metadata = node.metadata.top[0];
if (!metadata) {
return { name: null, provider: null, platform: null };
}
return {
name: metadata.metrics['host.name'] || null,
provider: metadata.metrics['cloud.provider'] || null,
platform: metadata.metrics['host.os.platform'] || null,
};
};

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { TopNodesRequest } from '../../../../common/http_api/overview_api';
import { MetricsSourceConfiguration } from '../../../../common/metrics_sources';
import { ESSearchClient } from '../../../lib/metrics/types';
import { convertESResponseToTopNodesResponse } from './convert_es_response_to_top_nodes_response';
import { createTopNodesQuery } from './create_top_nodes_query';
import { ESResponseForTopNodes } from './types';
export const queryTopNodes = async (
options: TopNodesRequest,
client: ESSearchClient,
source: MetricsSourceConfiguration
) => {
const params = {
index: source.configuration.metricAlias,
body: createTopNodesQuery(options, source),
};
const response = await client<{}, ESResponseForTopNodes>(params);
return convertESResponseToTopNodesResponse(response);
};

View file

@ -0,0 +1,48 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
type NumberOrNull = number | null;
interface TopMetric {
sort: string[];
metrics: Record<string, string | null>;
}
interface NodeMetric {
value: NumberOrNull;
}
interface NodeMetrics {
doc_count: number;
uptime: NodeMetric;
cpu: NodeMetric;
iowait: NodeMetric;
load: NodeMetric;
rx: NodeMetric;
tx: NodeMetric;
}
interface TimeSeriesMetric extends NodeMetrics {
key_as_string: string;
key: number;
}
export interface NodeBucket extends NodeMetrics {
key: string;
metadata: {
top: TopMetric[];
};
timeseries: {
buckets: TimeSeriesMetric[];
};
}
export interface ESResponseForTopNodes {
nodes: {
buckets: NodeBucket[];
};
}

View file

@ -0,0 +1,71 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { EuiIcon } from '@elastic/eui';
import React from 'react';
import { StringOrNull } from '../../../..';
import aixLogo from './logos/aix.svg';
import androidLogo from './logos/android.svg';
import darwinLogo from './logos/darwin.svg';
import dragonflyLogo from './logos/dragonfly.svg';
import freebsdLogo from './logos/freebsd.svg';
import illumosLogo from './logos/illumos.svg';
import linuxLogo from './logos/linux.svg';
import solarisLogo from './logos/solaris.svg';
import netbsdLogo from './logos/netbsd.svg';
interface Props {
name: StringOrNull;
id: StringOrNull;
provider: StringOrNull;
platform: StringOrNull;
timerange: { from: number; to: number };
}
export function HostLink({ name, id, provider, platform, timerange }: Props) {
const providerLogo =
provider === 'aws'
? 'logoAWS'
: provider === 'gcp'
? 'logoGCP'
: provider === 'azure'
? 'logoAzure'
: 'compute';
const platformLogo =
platform === 'darwin'
? darwinLogo
: platform === 'windows'
? 'logoWindows'
: platform === 'linux'
? linuxLogo
: platform === 'aix'
? aixLogo
: platform === 'andriod'
? androidLogo
: platform === 'dragonfly'
? dragonflyLogo
: platform === 'illumos'
? illumosLogo
: platform === 'freebsd'
? freebsdLogo
: platform === 'solaris'
? solarisLogo
: platform === 'netbsd'
? netbsdLogo
: 'empty';
const link = `../../app/metrics/link-to/host-detail/${id}?from=${timerange.from}&to=${timerange.to}`;
return (
<>
{platformLogo !== null && <EuiIcon type={platformLogo} title={`${platform}`} />}
&nbsp;
{providerLogo !== null && <EuiIcon type={providerLogo} title={`${provider}`} />}
&nbsp;
<a href={link}>{name}</a>
</>
);
}

View file

@ -5,49 +5,56 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiProgress, EuiSpacer } from '@elastic/eui';
import {
Criteria,
Direction,
EuiBasicTable,
EuiBasicTableColumn,
EuiTableSortingType,
} from '@elastic/eui';
import numeral from '@elastic/numeral';
import { i18n } from '@kbn/i18n';
import React, { useContext } from 'react';
import styled, { ThemeContext } from 'styled-components';
import React, { useState, useCallback } from 'react';
import {
MetricsFetchDataResponse,
MetricsFetchDataSeries,
NumberOrNull,
StringOrNull,
} from '../../../..';
import { SectionContainer } from '../';
import { getDataHandler } from '../../../../data_handler';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { useHasData } from '../../../../hooks/use_has_data';
import { useTimeRange } from '../../../../hooks/use_time_range';
import { StyledStat } from '../../styled_stat';
import { HostLink } from './host_link';
import { formatDuration } from './lib/format_duration';
import { MetricWithSparkline } from './metric_with_sparkline';
const SPARK_LINE_COLUMN_WIDTH = '120px';
const COLOR_ORANGE = 7;
const COLOR_BLUE = 1;
const COLOR_GREEN = 0;
const COLOR_PURPLE = 3;
interface Props {
bucketSize?: string;
}
/**
* EuiProgress doesn't support custom color, when it does this component can be removed.
*/
const StyledProgress = styled.div<{ color?: string }>`
progress {
&.euiProgress--native {
&::-webkit-progress-value {
background-color: ${(props) => props.color};
}
const percentFormatter = (value: NumberOrNull) =>
value === null ? '' : numeral(value).format('0[.0]%');
&::-moz-progress-bar {
background-color: ${(props) => props.color};
}
}
const numberFormatter = (value: NumberOrNull) =>
value === null ? '' : numeral(value).format('0[.0]');
&.euiProgress--indeterminate {
&:before {
background-color: ${(props) => props.color};
}
}
}
`;
const bytesPerSecondFormatter = (value: NumberOrNull) =>
value === null ? '' : numeral(value).format('0b') + '/s';
export function MetricsSection({ bucketSize }: Props) {
const theme = useContext(ThemeContext);
const { forceUpdate, hasData } = useHasData();
const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange();
const [sortDirection, setSortDirection] = useState<Direction>('asc');
const [sortField, setSortField] = useState<keyof MetricsFetchDataSeries>('uptime');
const [sortedData, setSortedData] = useState<MetricsFetchDataResponse | null>(null);
const { data, status } = useFetcher(
() => {
@ -64,16 +71,138 @@ export function MetricsSection({ bucketSize }: Props) {
[bucketSize, relativeStart, relativeEnd, forceUpdate]
);
const handleTableChange = useCallback(
({ sort }: Criteria<MetricsFetchDataSeries>) => {
if (sort) {
const { field, direction } = sort;
setSortField(field);
setSortDirection(direction);
if (data) {
(async () => {
const response = await data.sort(field, direction);
setSortedData(response || null);
})();
}
}
},
[data, setSortField, setSortDirection]
);
if (!hasData.infra_metrics?.hasData) {
return null;
}
const isLoading = status === FETCH_STATUS.LOADING;
const isPending = status === FETCH_STATUS.LOADING;
if (isLoading || isPending) {
return <pre>Loading</pre>;
}
const { appLink, stats } = data || {};
if (!data) {
return <pre>No Data</pre>;
}
const cpuColor = theme.eui.euiColorVis7;
const memoryColor = theme.eui.euiColorVis0;
const columns: Array<EuiBasicTableColumn<MetricsFetchDataSeries>> = [
{
field: 'uptime',
name: i18n.translate('xpack.observability.overview.metrics.colunms.uptime', {
defaultMessage: 'Uptime',
}),
sortable: true,
width: '80px',
render: (value: NumberOrNull) => (value == null ? 'N/A' : formatDuration(value / 1000)),
},
{
field: 'name',
name: i18n.translate('xpack.observability.overview.metrics.colunms.hostname', {
defaultMessage: 'Hostname',
}),
sortable: true,
truncateText: true,
isExpander: true,
render: (value: StringOrNull, record: MetricsFetchDataSeries) => (
<HostLink
id={record.id}
name={value}
provider={record.provider}
platform={record.platform}
timerange={{ from: absoluteStart, to: absoluteEnd }}
/>
),
},
{
field: 'cpu',
name: i18n.translate('xpack.observability.overview.metrics.colunms.cpu', {
defaultMessage: 'CPU %',
}),
sortable: true,
width: SPARK_LINE_COLUMN_WIDTH,
render: (value: NumberOrNull, record: MetricsFetchDataSeries) => (
<MetricWithSparkline
id="cpu"
value={value}
formatter={percentFormatter}
timeseries={record.timeseries}
color={COLOR_ORANGE}
/>
),
},
{
field: 'load',
name: i18n.translate('xpack.observability.overview.metrics.colunms.load15', {
defaultMessage: 'Load 15',
}),
sortable: true,
width: SPARK_LINE_COLUMN_WIDTH,
render: (value: NumberOrNull, record: MetricsFetchDataSeries) => (
<MetricWithSparkline
id="load"
value={value}
formatter={numberFormatter}
timeseries={record.timeseries}
color={COLOR_BLUE}
/>
),
},
{
field: 'rx',
name: 'RX',
sortable: true,
width: SPARK_LINE_COLUMN_WIDTH,
render: (value: NumberOrNull, record: MetricsFetchDataSeries) => (
<MetricWithSparkline
id="rx"
value={value}
formatter={bytesPerSecondFormatter}
timeseries={record.timeseries}
color={COLOR_GREEN}
/>
),
},
{
field: 'tx',
name: 'TX',
sortable: true,
width: SPARK_LINE_COLUMN_WIDTH,
render: (value: NumberOrNull, record: MetricsFetchDataSeries) => (
<MetricWithSparkline
id="tx"
value={value}
formatter={bytesPerSecondFormatter}
timeseries={record.timeseries}
color={COLOR_PURPLE}
/>
),
},
];
const sorting: EuiTableSortingType<MetricsFetchDataSeries> = {
sort: { field: sortField, direction: sortDirection },
};
const viewData = sortedData || data;
const { appLink } = data || {};
return (
<SectionContainer
@ -88,52 +217,12 @@ export function MetricsSection({ bucketSize }: Props) {
}}
hasError={status === FETCH_STATUS.FAILURE}
>
<EuiFlexGroup>
<EuiFlexItem>
<StyledStat
title={numeral(stats?.hosts.value).format('0a')}
description={i18n.translate('xpack.observability.overview.metrics.hosts', {
defaultMessage: 'Hosts',
})}
isLoading={isLoading}
/>
</EuiFlexItem>
<EuiFlexItem>
<StyledStat
title={numeral(stats?.cpu.value).format('0.0%')}
description={i18n.translate('xpack.observability.overview.metrics.cpuUsage', {
defaultMessage: 'CPU usage',
})}
isLoading={isLoading}
color={cpuColor}
>
<EuiSpacer size="s" />
<StyledProgress color={cpuColor}>
<EuiProgress
value={stats?.cpu.value}
max={1}
style={{ width: '100px' }}
color="accent"
/>
</StyledProgress>
</StyledStat>
</EuiFlexItem>
<EuiFlexItem>
<StyledStat
title={numeral(stats?.memory.value).format('0.0%')}
description={i18n.translate('xpack.observability.overview.metrics.memoryUsage', {
defaultMessage: 'Memory usage',
})}
isLoading={isLoading}
color={memoryColor}
>
<EuiSpacer size="s" />
<StyledProgress color={memoryColor}>
<EuiProgress value={stats?.memory.value} max={1} style={{ width: '100px' }} />
</StyledProgress>
</StyledStat>
</EuiFlexItem>
</EuiFlexGroup>
<EuiBasicTable
onChange={handleTableChange}
sorting={sorting}
items={viewData?.series ?? []}
columns={columns}
/>
</SectionContainer>
);
}

View file

@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { formatDuration } from './format_duration';
describe('formatDuration(seconds)', () => {
it('should work for less then a minute', () => {
expect(formatDuration(56)).toBe('56s');
});
it('should work for less then a hour', () => {
expect(formatDuration(2000)).toBe('33m 20s');
});
it('should work for less then a day', () => {
expect(formatDuration(74566)).toBe('20h 42m');
});
it('should work for more then a day', () => {
expect(formatDuration(86400 * 3 + 3600 * 4)).toBe('3d 4h');
expect(formatDuration(86400 * 419 + 3600 * 6)).toBe('419d 6h');
});
});

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
const MINUTE = 60;
const HOUR = 3600;
const DAY = 86400;
export const formatDuration = (seconds: number) => {
if (seconds < MINUTE) {
return `${Math.floor(seconds)}s`;
}
if (seconds < HOUR) {
return `${Math.floor(seconds / MINUTE)}m ${Math.floor(seconds % MINUTE)}s`;
}
if (seconds < DAY) {
return `${Math.floor(seconds / HOUR)}h ${Math.floor((seconds % HOUR) / MINUTE)}m`;
}
return `${Math.floor(seconds / DAY)}d ${Math.floor((seconds % DAY) / HOUR)}h`;
};

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg3767"
width="109.84255"
height="109.77177"
viewBox="0 0 109.84255 109.77177"
sodipodi:docname="IBM_AIX_logo.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata3773">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3771" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview3769"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="5.8428571"
inkscape:cx="79.033262"
inkscape:cy="57.027081"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3767" />
<path
style="fill:#7bba00"
d="M 40.529212,108.39939 C 21.675193,103.22264 6.4461125,87.852341 1.4064525,68.91385 c -1.87527,-7.047068 -1.87527,-20.937808 0,-27.984876 C 6.4746925,21.883076 21.882812,6.4749572 40.928713,1.4067222 c 7.032809,-1.87147696 20.93352,-1.87643396 27.94709,-0.01 19.322391,5.142121 34.427877,20.2476058 39.569997,39.5699988 1.86646,7.013571 1.86151,20.914278 -0.01,27.947095 -5.06823,19.045905 -20.476345,34.454024 -39.522247,39.522254 -6.75167,1.79666 -21.77791,1.77723 -28.38437,-0.0367 z m 27.85038,-3.00917 c 8.65777,-2.25506 16.689262,-6.936519 23.381552,-13.628809 20.437366,-20.437366 20.437366,-53.242632 0,-73.679999 -20.437362,-20.4373668 -53.242632,-20.4373668 -73.680002,0 C 1.7508125,34.411741 -1.8950475,59.476781 9.0680625,80.045686 15.190732,91.532981 28.318512,101.92138 41.033472,105.34086 c 7.1516,1.92331 20.06208,1.94661 27.34612,0.0494 z M 42.025773,101.4015 C 25.109833,96.656251 11.383633,82.087761 7.8616025,65.140888 6.2607425,57.438056 7.1896525,44.802606 9.8791925,37.696646 14.478623,25.544623 25.323093,14.686785 37.801943,9.7394702 c 8.130789,-3.223502 26.10761,-3.223502 34.23841,0 12.413802,4.9215238 23.136912,15.6193618 28.023237,27.9571758 3.26361,8.240532 3.28422,26.159632 0.0395,34.343971 -4.886785,12.326198 -15.898375,23.336694 -27.938907,27.936124 -7.53241,2.877349 -22.44677,3.582409 -30.1384,1.424759 z M 24.921143,63.421412 c 0.509005,-1.542299 0.971415,-3.303528 1.65484,-3.786073 0.858842,-0.606403 2.294214,-0.227374 5.602102,-0.227374 3.238343,0 4.646661,-0.298692 5.537231,0.431075 0.726917,0.595665 1.123168,2.033622 1.770277,3.582372 0.492919,1.17972 1.049114,2.580874 1.432322,3.234937 0.228656,0.390273 1.455362,0.265063 2.502057,0.265063 h 2.47199 l -1.88018,-4.75 c -6.278764,-15.86238 -8.45464,-21.339783 -9.830353,-23.431564 -0.521837,-0.450914 -1.200964,-0.342819 -1.808941,-0.325711 -0.665735,0.01873 -1.246158,-0.02053 -1.441342,0.216377 -1.067078,1.318902 -2.718101,5.472063 -4.990584,11.040898 -2.412709,5.9125 -4.985149,12.2125 -5.71651,14 -0.715922,1.749766 -1.481879,2.852208 -1.158158,3.296022 0.257412,0.352905 1.392612,0.210702 2.435427,0.210702 0.996126,0 2.04455,0.152557 2.336632,-0.46839 0.531157,-1.129208 0.655915,-1.993672 1.08319,-3.288334 z m 4.658479,-11.75 c 2.37412,-6.143881 2.888303,-6.339977 4.70682,-1.795058 1.34807,3.369157 2.62182,5.209822 1.877548,5.871813 -0.514399,0.457531 -2.39504,0.173245 -4.234748,0.173245 h -3.9919 z m 24.341521,1.25 -0.08558,-15.369193 -2.585574,-0.04279 -2.457213,0.128361 0.128362,15.283619 v 14 h 2.5 2.5 z m 13.67013,8.476909 4.084765,-6.551768 4.076196,6.430747 c 2.077877,3.278127 2.287986,4.935394 3.442385,5.466405 1.065842,0.490276 2.053227,0.315385 3.23669,0.328983 l 2.633135,0.03025 -5.132162,-7.071222 c -2.756119,-3.78933 -5.695735,-7.469747 -5.695735,-7.864931 0,-0.395184 3.128906,-4.551238 5.937556,-8.057711 l 6.074512,-7.583755 c -1.17765,-0.03687 -3.043903,-0.09631 -4.218264,-9.75e-4 -1.127135,0.501727 -1.807346,2.273229 -5.464838,7.371239 -1.927091,2.686084 -4.748873,5.832962 -5.043973,5.847145 -0.2951,0.01418 -2.024417,-2.814636 -4.077477,-5.564636 -1.568849,-2.269981 -2.710041,-4.965278 -4.029981,-7.23751 -0.21461,-0.143099 -0.607254,-0.0372 -2.145576,-0.02458 -1.282918,0.05953 -2.483992,0.162093 -2.69654,0.239294 0.583197,0.605963 3.979442,7.254865 5.988896,9.892259 l 4.165629,5.384156 -5.414189,7.365844 -5.53521,7.123803 h 2.87984 c 1.070968,0 2.378944,0.05647 3.439495,-0.374776 0.976441,-0.397042 2.076735,-3.14555 3.857907,-5.571887 z"
id="path3781"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssscccscccssssscccsssscsscccsssssscscscccsssccssscccccccccccccsssccssccscccccscccsscc" />
<path
style="fill:#ffffff;stroke-width:0.17114915"
d="m 19.080865,66.883462 c -0.05755,-0.09311 0.237924,-0.959553 0.6566,-1.925428 0.418675,-0.965875 2.583388,-6.223128 4.810473,-11.682786 4.280647,-10.493927 5.996331,-14.311359 6.569995,-14.618375 0.191177,-0.102314 0.853268,-0.186026 1.471315,-0.186026 0.889997,0 1.193881,0.07016 1.461044,0.337323 0.739723,0.739723 2.021963,3.675589 6.505369,14.894951 4.053708,10.14408 5.137748,12.899398 5.137748,13.058681 0,0.06589 -0.989287,0.119803 -2.198412,0.119803 -1.876387,0 -2.23812,-0.04387 -2.469474,-0.299518 -0.149083,-0.164734 -0.709218,-1.377754 -1.244745,-2.695599 -1.310203,-3.22419 -1.706621,-3.970631 -2.260629,-4.256691 -0.365906,-0.188935 -1.598571,-0.256028 -5.575182,-0.303448 l -5.10541,-0.06088 -0.491936,0.550219 c -0.356799,0.39907 -0.75308,1.360024 -1.44257,3.498138 -0.522848,1.621357 -1.067248,3.125898 -1.209777,3.343426 -0.247737,0.378094 -0.352701,0.395503 -2.384463,0.395503 -1.216717,0 -2.170048,-0.07237 -2.229946,-0.169293 z M 35.937908,55.878784 c 0.264757,-0.133272 0.44818,-0.389778 0.481138,-0.672852 0.05555,-0.47712 -2.63189,-6.907207 -3.30319,-7.90335 -0.684189,-1.015268 -1.306292,-0.727796 -2.184255,1.009341 -0.408506,0.808268 -3.037703,7.349197 -3.037703,7.55721 0,0.0271 1.058985,0.07306 2.353301,0.10213 1.294315,0.02908 3.007946,0.06862 3.808068,0.08788 0.89667,0.02158 1.618915,-0.04761 1.882641,-0.18036 z"
id="path3866"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;stroke-width:0.17114915"
d="m 48.987069,52.29114 0.04375,-14.590464 2.325297,-0.04744 2.325296,-0.04744 0.113579,8.247931 c 0.06247,4.536361 0.113579,11.123416 0.113579,14.637898 v 6.38997 H 51.425944 48.94332 Z"
id="path3868"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;stroke-width:0.17114915"
d="m 79.727121,66.851128 c -0.85727,-0.2284 -1.177295,-0.619809 -2.432915,-2.9756 -1.144204,-2.146748 -5.328854,-8.851622 -5.580082,-8.940708 -0.1324,-0.04695 -2.986052,4.426418 -5.583983,8.753417 -1.474227,2.455409 -1.837623,2.822 -3.004647,3.031059 -0.531546,0.09522 -1.906344,0.151439 -3.055106,0.124932 l -2.088658,-0.0482 2.717701,-3.508557 c 3.576257,-4.616955 7.985013,-10.608323 7.985013,-10.851394 0,-0.106199 -0.924499,-1.385648 -2.054442,-2.843219 -1.129944,-1.457572 -2.374637,-3.120965 -2.765984,-3.696429 -0.806735,-1.186277 -4.992125,-8.40455 -4.992125,-8.609596 0,-0.128264 2.422144,-0.35633 3.784359,-0.35633 0.742148,0 0.551171,-0.268391 2.76175,3.881244 1.169684,2.195697 5.220907,8.251563 5.89353,8.80979 0.558703,0.463683 4.005376,-3.652187 7.832823,-9.353626 1.011074,-1.506113 2.06326,-2.950183 2.338194,-3.209047 0.487929,-0.459409 0.548865,-0.47066 2.549134,-0.47066 h 2.049256 l -3.991875,5.006113 c -3.605745,4.521874 -6.930723,8.869512 -7.713388,10.085789 -0.362784,0.563773 -0.571288,0.213952 2.990956,5.018123 1.465758,1.976772 3.692783,5.018948 4.948944,6.760391 1.256163,1.741442 2.357949,3.262531 2.448415,3.380196 0.129839,0.168874 -0.317591,0.21021 -2.124199,0.196248 -1.258774,-0.0097 -2.569475,-0.0925 -2.912671,-0.183938 z"
id="path3870"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;stroke-width:0.17114915"
d="M 51.255756,106.6583 C 43.119239,106.1642 38.624857,105.0147 32.258201,101.79943 22.161257,96.700285 13.579278,88.485987 8.8304881,79.375439 5.6470204,73.26796 3.6779954,66.43463 3.0604566,59.351042 2.7907868,56.257748 2.9548764,50.530906 3.3965275,47.621935 4.8201273,38.245281 8.4844757,29.742615 14.199931,22.553976 16.054428,20.221475 20.306158,15.966899 22.588275,14.160018 34.242011,4.9330945 48.934327,1.1395062 63.578495,3.5762524 82.205532,6.6757363 98.015173,20.101811 104.16418,38.042974 c 2.11361,6.166952 2.92148,11.536084 2.75138,18.285886 -0.20419,8.102942 -2.02082,15.219145 -5.71977,22.405848 -2.445813,4.75199 -5.472922,8.838596 -9.61613,12.981803 -4.366499,4.366499 -8.498003,7.370264 -13.710212,9.967859 -5.556494,2.76918 -10.253466,4.13621 -16.252643,4.73026 -1.908468,0.18897 -8.650625,0.34754 -10.361049,0.24367 z m 9.257353,-4.26695 c 4.888302,-0.46749 9.028455,-1.32276 12.057236,-2.490786 3.452375,-1.331376 7.947547,-3.943374 11.374898,-6.609582 8.808416,-6.852247 15.792828,-17.140133 17.522567,-25.810355 0.81191,-4.069629 0.96154,-6.013885 0.96154,-12.493888 0,-6.61649 -0.16256,-8.650862 -1.02267,-12.798627 -0.58489,-2.820555 -1.28773,-4.789843 -2.823227,-7.910419 C 94.187715,25.344276 86.652682,17.432241 77.728553,12.379355 73.8416,10.178544 70.310973,8.8675893 66.48803,8.2056442 62.41155,7.4997991 61.026611,7.4070501 54.678739,7.41478 48.100096,7.42279 46.61979,7.5438387 42.167471,8.4378514 c -2.741646,0.5505148 -4.554564,1.2013161 -7.85548,2.8199606 -4.945967,2.425315 -9.26807,5.569162 -13.520782,9.834857 -6.084991,6.103569 -10.268779,13.077487 -12.0643105,20.109888 -0.4375484,1.713707 -1.1227522,5.73344 -1.4014946,8.221835 -0.3410683,3.044793 -0.2898297,11.074714 0.086276,13.520783 1.1570791,7.52527 4.2666491,14.62485 9.3327991,21.308068 1.670039,2.2031 6.635805,7.168866 8.838906,8.838905 7.078064,5.365459 14.734769,8.636312 21.90709,9.358432 2.59609,0.26138 10.023425,0.2276 13.022634,-0.0592 z"
id="path3872"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-147 -70 294 345">
<g fill="#a4c639">
<use stroke-width="14.4" xlink:href="#b" stroke="#FFF"/>
<use xlink:href="#a" transform="scale(-1,1)"/>
<g id="a" stroke="#FFF" stroke-width="7.2">
<rect rx="6.5" transform="rotate(29)" height="86" width="13" y="-86" x="14"/>
<rect id="c" rx="24" height="133" width="48" y="41" x="-143"/>
<use y="97" x="85" xlink:href="#c"/>
</g>
<g id="b">
<ellipse cy="41" rx="91" ry="84"/>
<rect rx="22" height="182" width="182" y="20" x="-91"/>
</g>
</g>
<g stroke="#FFF" stroke-width="7.2" fill="#FFF">
<path d="m-95 44.5h190"/><circle cx="-42" r="4"/><circle cx="42" r="4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 728 B

View file

@ -0,0 +1 @@
<svg width="842" height="1e3" xmlns="http://www.w3.org/2000/svg"><path d="M702 960c-54.2 52.6-114 44.4-171 19.6-60.6-25.3-116-26.9-180 0-79.7 34.4-122 24.4-170-19.6-271-279-231-704 77-720 74.7 4 127 41.3 171 44.4 65.4-13.3 128-51.4 198-46.4 84.1 6.8 147 40 189 99.7-173 104-132 332 26.9 396-31.8 83.5-72.6 166-141 227zM423 237C414.9 113 515.4 11 631 1c15.9 143-130 250-208 236z"/></svg>

After

Width:  |  Height:  |  Size: 386 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61.096 64.37" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><style><![CDATA[.B{stroke-width:1.096}.C{fill-rule:nonzero}]]></style><use xlink:href="#B" x=".548" y=".822"/><defs><radialGradient id="A" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"><stop offset="0%" stop-color="#fff"/><stop offset="4.2%" stop-color="#f7f9d8"/><stop offset="9.1%" stop-color="#eff2b2"/><stop offset="14.3%" stop-color="#e8ed91"/><stop offset="19.9%" stop-color="#e2e976"/><stop offset="26.1%" stop-color="#dde562"/><stop offset="33%" stop-color="#dae353"/><stop offset="41.2%" stop-color="#d9e14b"/><stop offset="54.5%" stop-color="#d8e148"/><stop offset="67.9%" stop-color="#d6e048"/><stop offset="74.7%" stop-color="#cfdd47"/><stop offset="79.9%" stop-color="#c2d946"/><stop offset="84.4%" stop-color="#b1d245"/><stop offset="88.5%" stop-color="#99ca44"/><stop offset="92.1%" stop-color="#7bc143"/><stop offset="92.7%" stop-color="#75c044"/><stop offset="100%" stop-color="#073800"/></radialGradient></defs><symbol id="B" overflow="visible"><g class="C"><path d="M13.881 18.842A18.8 18.8 0 0 1 32.723 0a18.8 18.8 0 0 1 18.842 18.842c0 10.439-8.404 18.842-18.842 18.842s-18.842-8.404-18.842-18.842z" fill="url(#A)" stroke-width="1.644"/><path d="M31.045 24.489H34.4c0 12.665-1.121 38.144-1.678 38.144s-1.676-25.478-1.676-38.143z" stroke="none" fill="#ed1c24"/></g><g fill="none" class="B"><path d="M31.045 24.489c0 12.665 1.121 38.143 1.676 38.143M34.4 24.489c0 12.665-1.121 38.144-1.678 38.144"/><path d="M31.045 24.489H34.4m-3.326 4.331h3.3m-3.224 3.781h3.143m-3.048 3.781h2.954m-2.838 3.778h2.722m-2.581 3.777h2.446m-2.3 3.772h2.146m-1.972 3.773h1.801"/></g><path d="M29.582 18.842c0-4.101 1.4-7.403 3.14-7.403s3.14 3.302 3.14 7.403-1.4 7.403-3.14 7.403-3.14-3.302-3.14-7.403z" stroke="none" fill="#ed1c24" class="C"/><path d="M29.584 18.842c0-4.101 1.4-7.403 3.139-7.403s3.139 3.302 3.139 7.403-1.4 7.403-3.139 7.403-3.139-3.302-3.139-7.403z" fill="none" class="B"/><g stroke="none" class="C"><g fill="#fde92b"><path d="M35.859 10.858c0 .748-.375 1.425-.978 1.903h-.002L33.598 8.34c1.307.316 2.261 1.323 2.261 2.518z"/><path d="M33.598 8.34l1.281 4.421c-.483 0-1.298-2.27-1.776-4.504a3.6 3.6 0 0 1 .495.085z"/></g><path d="M34.879 12.761c-.562.447-1.324.721-2.158.721s-1.596-.276-2.158-.721c.483 0 1.298-2.27 1.776-4.504a3.7 3.7 0 0 1 .382-.02l.382.018c.478 2.235 1.292 4.504 1.776 4.504zm-2.158-7.445l.877 3.026c-.16-.04-.325-.068-.496-.085-.23-1.073-.382-2.138-.382-2.941z" fill="#9a090d"/><g fill="#000"><path d="M33.104 8.255l-.382-.018a3.7 3.7 0 0 0-.382.02c.23-1.073.382-2.138.382-2.941 0 .803.153 1.868.382 2.941z"/><path d="M31.846 8.34l.877-3.026c0 .803-.153 1.868-.382 2.941-.169.018-.335.046-.496.085z"/></g><g fill="#fde92b"><path d="M32.339 8.255c-.478 2.235-1.292 4.504-1.776 4.504l1.281-4.421c.16-.037.325-.068.496-.085z"/><path d="M31.846 8.34l-1.281 4.421c-.603-.478-.978-1.154-.978-1.903 0-1.195.956-2.202 2.261-2.518z"/></g></g><g fill="none"><g stroke-width="1.028"><path d="M32.339 8.255l.382-.018.382.018c.167.016.332.044.494.085 1.305.316 2.261 1.324 2.261 2.518 0 .748-.375 1.425-.978 1.903h-.002c-.562.447-1.324.721-2.158.721s-1.596-.276-2.158-.721c-.603-.478-.978-1.154-.978-1.903 0-1.195.956-2.202 2.261-2.518a3.89 3.89 0 0 1 .496-.085z"/><path d="M30.563 12.761c.483 0 1.298-2.27 1.776-4.504.23-1.073.382-2.138.382-2.941m0-.002c0 .803.152 1.868.382 2.941.478 2.235 1.292 4.504 1.776 4.504"/></g><path d="M0 51.855h1.799" class="B"/></g><g class="C"><path d="M32.721 17.689S14.098 19.966 7.846 8.205c-5.616-10.571 24.878 8.15 24.878 8.15zm.003 3.511S17.961 32.134 7.192 24.594c-9.675-6.771 25.532-4.679 25.532-4.679z" class="B"/><path d="M32.724 17.679s18.623 2.277 24.874-9.484c5.616-10.571-24.877 8.15-24.877 8.15zm-.003 3.511s14.762 10.934 25.533 3.394c9.675-6.772-25.533-4.673-25.533-4.673z" class="B"/></g></symbol></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="256px" height="252px" viewBox="0 0 256 252" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g fill="#B5010F">
<path d="M252.722963,5.10923976 C266.230721,18.6106793 228.784285,77.9582562 222.453709,84.2919919 C216.123132,90.6130917 200.043973,84.7974272 186.542533,71.2928287 C173.034776,57.7913892 167.215952,41.7090709 173.546529,35.3784942 C179.873947,29.0447585 239.218365,-8.39851769 252.722963,5.10923976"></path>
<path d="M63.3047797,19.3941039 C42.6830209,7.69327755 13.3393448,-5.32168052 4.00458729,4.01307703 C-5.4533701,13.4678754 8.0385925,43.4717763 19.8626187,64.1314428 C30.3851491,45.8378452 45.3523509,30.4378645 63.3047797,19.3941039"></path>
<path d="M232.123317,79.6356695 C234.021858,86.0768102 233.680689,91.3965163 230.600693,94.4701945 C223.407718,101.666329 203.976891,94.0058259 186.4604,77.3359391 C185.237878,76.2397763 184.024834,75.102547 182.833902,73.9084562 C176.500166,67.5715616 171.572172,60.8271597 168.41952,54.6166239 C162.284799,43.610771 160.74954,33.8906191 165.386908,29.2532506 C167.914085,26.7292332 171.957567,26.0405777 176.88872,26.9282483 C180.104551,24.8938714 183.901634,22.6288896 188.065157,20.3070464 C171.136234,11.4777241 151.888628,6.48970982 131.472202,6.48970982 C63.7533535,6.48970982 8.85360686,61.3799796 8.85360686,129.105146 C8.85360686,196.817677 63.7533535,251.714264 131.472202,251.714264 C199.191051,251.714264 254.087638,196.817677 254.087638,129.105146 C254.087638,107.235594 248.347789,86.7275581 238.321217,68.9488727 C236.154163,72.9039036 234.04713,76.5272426 232.123317,79.6356695"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 106 KiB

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="744.09448"
height="578.2677"
id="svg2206">
<defs
id="defs2208" />
<g
transform="translate(88.531636,-126.60988)"
id="layer1">
<g
transform="matrix(3.5433071,0,0,3.5433071,-70.892703,-365.08493)"
style="fill-rule:evenodd"
id="g2195">
<path
d="M 37.481557,153.14346 C 37.203039,153.14394 36.863498,153.22332 36.463039,153.44438 C 35.131151,154.18323 35.826466,155.55086 35.826466,155.55086 L 60.86117,208.47907 L 66.925981,208.47907 L 38.62739,153.8842 C 38.62739,153.8842 38.317112,153.14202 37.481557,153.14346 z M 82.597266,254.45126 L 101.61346,294.68273 C 101.61345,294.68269 102.6954,296.80406 104.96993,296.98595 L 105.59493,296.98595 C 106.20688,296.93987 106.89488,296.75939 107.65512,296.37254 C 111.76718,294.27999 109.6932,291.00218 109.69215,291.00218 L 90.756982,254.45126 L 82.597266,254.45126 z "
style="fill:#777777"
id="path10" />
<path
d="M 179.4878,150.25776 C 170.59174,145.98808 162.01314,144.08296 153.49923,143.74845 L 147.88637,143.74845 C 135.58336,144.20882 123.29912,147.59346 110.26566,151.49385 C 86.088381,158.72534 64.582751,162.63925 40.423974,152.7823 C 43.055993,157.48492 44.373578,159.83597 47.00691,164.53505 C 49.424493,168.85775 51.845358,173.17993 54.26386,177.50079 C 56.896667,182.20262 58.212939,184.5517 60.846271,189.25262 C 80.081429,194.68923 96.010947,187.63871 113.10411,179.09344 C 133.63008,168.8378 152.17023,159.61143 175.62205,164.95723 C 155.80317,155.03269 137.83651,157.4924 117.1133,163.11471 C 137.40226,152.78585 156.50408,144.75265 179.4878,150.25776 L 179.4878,150.25776 z "
style="fill:#f26711"
id="path14" />
<path
d="M 38.945891,234.7459 C 38.945891,238.71072 38.945891,242.54996 39.067544,244.56479 C 38.641692,245.29353 36.934213,245.96754 35.471353,245.96754 C 35.409673,245.96754 33.397207,242.85652 30.531986,239.31807 L 16.446299,221.87688 C 12.971761,217.48567 10.89814,214.98659 9.8005027,214.07124 C 9.4963034,214.68003 9.4963034,215.71625 9.4963034,217.97321 L 9.4963034,229.80601 C 9.4963034,234.74577 9.7393479,239.31807 10.410607,240.9661 C 10.959688,242.24576 12.361656,242.61203 13.946826,242.91518 L 15.654174,243.16059 C 16.141181,243.64944 16.019921,244.93093 15.654174,245.2934 C 12.361656,245.1745 9.9226811,245.11059 7.4838375,245.11059 C 5.2278022,245.11059 2.9722918,245.1745 0.65562663,245.2934 C 0.2893539,244.93093 0.1675692,243.64944 0.65562663,243.16059 L 1.6917152,242.97726 C 3.3380396,242.61098 4.4959129,242.24576 5.044469,240.9661 C 5.6541799,239.31794 5.8986679,234.74577 5.8986679,229.80601 L 5.8986679,214.31481 C 5.8986679,210.96192 5.8986679,209.98699 5.4717653,209.13279 C 5.044469,208.09578 4.1301651,207.48515 1.9959145,207.05917 L 0.2893539,206.81429 C 0.13712302,206.64014 0.047359301,206.34159 0.0219,206.02177 L 0.0219,205.6404 C 0.05851415,205.18791 0.22609935,204.77243 0.53239836,204.68096 C 3.3986695,204.79985 6.4468303,204.86285 8.9477473,204.86285 C 11.020449,204.86285 12.788952,204.80182 14.069529,204.68056 C 14.680158,207.42439 18.643017,212.05785 24.130152,218.58462 L 29.251934,224.62268 C 31.996289,227.79393 33.703243,229.92635 35.106523,231.33094 C 35.350093,230.71979 35.349962,229.68186 35.349962,228.58645 L 35.350093,220.1694 C 35.350093,215.23042 35.106523,210.65641 34.434739,209.00733 C 33.885658,207.72859 32.544976,207.36429 30.898652,207.05917 L 29.251934,206.81429 C 28.764926,206.32623 28.88658,205.04618 29.251934,204.68096 C 32.54537,204.79985 34.92319,204.86285 37.423189,204.86285 C 39.678305,204.86285 41.874104,204.80169 44.252318,204.68043 C 44.618591,205.04618 44.739326,206.32623 44.252318,206.81521 L 43.154681,206.9971 C 41.570036,207.36416 40.410719,207.72846 39.861114,209.01048 C 39.191691,210.65628 38.94681,215.23042 38.94681,220.1711 L 38.945891,234.7459 L 38.945891,234.7459 z "
style="fill:#f26711"
id="path16" />
<path
d="M 53.432365,227.97556 C 54.287482,227.97556 55.261629,227.85194 55.933807,227.4274 C 56.2384,227.24078 56.358741,226.63068 56.358741,226.02556 C 56.358872,224.01205 55.201393,222.66953 53.128297,222.66953 C 50.56675,222.66953 48.372263,225.1089 48.372263,227.05929 C 48.372263,227.9148 49.225018,227.97556 51.176854,227.97556 L 53.432365,227.97556 L 53.432365,227.97556 z M 49.40927,230.6585 C 48.006909,230.6585 47.884206,230.77923 47.884206,231.75522 C 47.884206,236.33015 50.811632,240.78159 56.481444,240.78159 C 58.189317,240.78159 60.506507,240.41729 62.152307,237.61073 C 62.823172,237.48947 63.738001,237.977 63.738001,239.01164 C 61.237478,244.19642 56.725932,245.96728 53.067142,245.96728 C 44.835651,245.96728 40.38526,240.17135 40.38526,233.52425 C 40.38526,225.83987 45.933813,219.86257 53.555068,219.86257 C 59.895878,219.86257 63.310705,223.94879 63.310705,228.64643 C 63.310705,229.80469 63.005981,230.6585 61.116612,230.6585 L 49.40927,230.6585 L 49.40927,230.6585 z "
style="fill:#f26711"
id="path18" />
<path
d="M 75.333269,224.01231 C 74.541144,224.01231 74.48012,224.0715 74.48012,225.41506 L 74.48012,234.55994 C 74.48012,237.977 74.48012,241.75849 78.748228,241.75849 C 79.601902,241.75849 80.576836,241.33211 81.309775,240.84458 C 81.918173,241.02608 82.284315,241.69642 82.161612,242.42883 C 80.454657,244.25757 77.162533,245.96728 73.382483,245.96728 C 68.320938,245.96728 66.553223,243.03907 66.553223,239.01177 L 66.553354,225.41493 C 66.553354,224.13252 66.492199,224.01218 65.394562,224.01218 L 63.505193,224.01218 C 62.833934,223.76362 62.650994,222.54735 63.138527,222.11913 C 65.028289,221.45063 66.735768,220.35103 68.199547,219.37649 C 69.29679,218.58436 70.821855,217.30483 72.711618,214.6173 C 73.137602,214.37518 74.236157,214.43764 74.541275,214.92373 L 74.541275,219.49827 C 74.541275,220.65614 74.60243,220.7173 75.699673,220.7173 L 81.126967,220.71717 C 81.431691,220.96021 81.613974,221.32832 81.613974,221.87648 C 81.613974,222.54735 81.43156,223.64315 80.821849,224.01218 L 75.333269,224.01231 L 75.333269,224.01231 z "
style="fill:#f26711"
id="path20" />
<path
d="M 97.353203,234.80495 C 97.353203,239.56243 97.963439,242.54996 102.72039,242.54996 C 107.23233,242.54983 109.60976,239.0749 109.60976,234.13422 C 109.60976,228.82805 106.56068,225.10916 100.70832,225.10916 C 97.353728,225.10916 97.353728,225.16939 97.353728,227.6106 L 97.353728,234.80403 L 97.353203,234.80495 z M 97.353203,220.71743 C 97.353203,222.30444 97.415276,222.42399 100.58562,222.42399 C 105.82918,222.42386 107.78049,219.07215 107.78049,215.41245 C 107.78049,210.10681 104.48745,207.4841 100.2801,207.4841 C 97.415276,207.4841 97.353203,207.974 97.353203,210.65641 L 97.353203,220.71743 z M 88.938379,214.80129 C 88.938379,208.64342 88.816594,207.974 86.255966,207.66704 L 84.609248,207.42164 C 84.060692,207.11639 83.938382,205.28778 84.853605,205.22663 C 89.487985,204.92256 93.938901,204.67715 100.03745,204.67715 C 105.88981,204.67715 109.79388,205.34933 112.47498,206.93542 C 115.09715,208.52059 116.68141,211.08318 116.68141,214.67898 C 116.68141,219.80299 112.35319,221.81507 110.4633,222.30444 C 109.8528,222.42386 109.24257,222.66966 109.24257,222.97438 C 109.24257,223.15667 109.549,223.33829 110.09808,223.46231 C 114.91474,224.49971 118.99899,227.66782 119.06054,233.58264 C 119.12209,239.19419 115.76841,242.48828 111.92813,243.83133 C 108.08509,245.17253 103.5133,245.35534 99.79349,245.35534 C 97.599003,245.35534 95.281813,245.10901 93.512917,245.10901 C 90.524073,245.10901 87.536543,245.17253 84.062004,245.29327 C 83.574997,244.92804 83.574997,243.34327 84.062004,243.16046 L 85.830507,242.79379 C 88.57355,242.24563 88.939823,241.81833 88.939823,236.32936 L 88.938379,214.80129 L 88.938379,214.80129 z "
style="fill:#777777"
id="path22" />
<path
d="M 132.35791,246.0871 C 126.74951,246.0871 123.27313,244.5014 121.99348,243.77083 C 120.83521,242.42923 120.04308,238.03842 120.04308,233.89078 C 120.46907,233.09905 121.87222,233.03658 122.35975,233.70745 C 123.57878,237.67136 127.66303,243.28146 132.84675,243.28146 C 137.3579,243.28146 139.43244,240.17175 139.43244,237.12359 C 139.43244,232.18422 134.79911,229.25693 131.1398,227.42779 C 126.74964,225.22963 121.99361,221.5732 121.93376,215.53384 C 121.9339,208.64355 127.23888,203.88476 136.07969,203.88476 C 138.09123,203.88476 140.59071,204.13017 143.031,204.86298 C 143.82325,205.10655 144.37128,205.22689 145.1037,205.34959 C 145.58939,206.69119 146.20133,209.98476 146.20133,214.07137 C 145.89595,214.80142 144.37128,214.8635 143.82312,214.25602 C 142.78611,211.14355 140.16302,206.69119 135.77313,206.69119 C 131.75003,206.69119 129.55554,209.31481 129.55554,212.36205 C 129.55554,215.16848 132.05279,217.72832 135.10187,219.31441 L 139.12785,221.45089 C 142.9075,223.46297 147.72496,226.99905 147.72496,233.70745 C 147.72509,241.20928 141.56433,246.0871 132.35791,246.0871 L 132.35791,246.0871 z "
style="fill:#777777"
id="path24" />
<path
d="M 161.11773,234.07136 C 161.11773,237.42739 161.24043,239.62188 162.33676,240.90337 C 163.43636,242.12371 165.2029,242.67188 167.3983,242.67188 C 177.94607,242.67188 181.54409,233.28251 181.54409,224.98672 C 181.54423,214.0089 175.75158,207.48397 164.71445,207.48397 C 163.07101,207.48384 161.90985,207.78896 161.54463,208.27885 C 161.17849,208.76534 161.11773,209.92374 161.11773,211.8131 L 161.11773,234.07228 L 161.11773,234.07136 z M 152.39923,214.7404 C 152.39923,208.94736 152.27705,207.78896 149.47194,207.48397 L 148.31406,207.36311 C 147.7054,207.05786 147.70527,205.28765 148.43677,205.22649 C 153.55868,204.92229 158.31366,204.67689 164.77796,204.67689 C 169.7777,204.67689 174.77612,205.16862 178.98452,206.6908 C 186.97296,209.55654 191.36128,216.75286 191.36128,224.37464 C 191.36141,232.54813 187.45944,239.13566 180.44843,242.61072 C 176.30263,244.68566 171.30119,245.47555 165.02114,245.47555 C 162.15684,245.47555 159.10487,245.10888 156.9113,245.10888 C 153.98361,245.10888 150.8739,245.17227 147.39976,245.29314 C 146.91236,244.92778 146.91236,243.46492 147.39976,243.1602 L 149.28965,242.85521 C 152.03322,242.36807 152.39936,241.9413 152.39936,236.32923 L 152.39923,214.7404 L 152.39923,214.7404 z "
style="fill:#777777"
id="path26" />
<path
d="M 189.07047,209.35746 C 189.07047,207.84775 189.60616,206.55746 190.67795,205.48857 C 191.74921,204.41954 193.04081,203.88437 194.55052,203.88437 C 196.05996,203.88437 197.35012,204.41954 198.41915,205.48857 C 199.48713,206.55746 200.0219,207.84775 200.0219,209.35746 C 200.0219,210.86862 199.48713,212.1589 198.41915,213.23108 C 197.35012,214.30234 196.05983,214.83856 194.55052,214.83856 C 193.04094,214.83856 191.74921,214.30247 190.67795,213.23108 C 189.60616,212.1589 189.07047,210.86862 189.07047,209.35746 z M 199.12466,209.35746 C 199.12466,208.09263 198.67925,207.01403 197.7866,206.12098 C 196.89422,205.22886 195.81626,204.78201 194.55052,204.78201 C 193.28582,204.78201 192.20524,205.22886 191.31036,206.12098 C 190.41495,207.01403 189.96771,208.09277 189.96771,209.35746 C 189.96771,210.62282 190.41495,211.70287 191.31036,212.59827 C 192.20524,213.49171 193.28582,213.9404 194.55065,213.9404 C 195.8164,213.94027 196.89408,213.49171 197.78674,212.59827 C 198.67939,211.70287 199.12466,210.62282 199.12466,209.35746 z M 196.25091,212.65339 L 194.53385,209.75051 L 193.55892,209.75051 L 193.55892,212.65326 L 192.60157,212.65326 L 192.60157,205.92046 L 194.32952,205.92046 C 195.95078,205.92046 196.76101,206.54211 196.76101,207.78384 C 196.76101,208.64775 196.32479,209.25878 195.45262,209.61481 L 197.29894,212.65326 L 196.25091,212.65339 z M 193.55892,206.73581 L 193.55892,208.98673 C 193.63949,208.99775 193.8496,209.00195 194.18844,209.00195 C 194.81351,209.00195 195.23437,208.92229 195.4496,208.76219 C 195.66535,208.60143 195.77322,208.29591 195.77322,207.84408 C 195.77335,207.09959 195.28805,206.72741 194.31863,206.72741 L 193.93897,206.72741 L 193.55892,206.73581 L 193.55892,206.73581 z "
style="fill:#777777"
id="path28" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) --><svg height="256" id="svg2" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:version="0.46" sodipodi:docname="distributions-solaris.svg" sodipodi:version="0.32" version="1.0" width="256" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
<metadata>
<rdf:RDF xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work rdf:about="">
<dc:title></dc:title>
<dc:description></dc:description>
<dc:subject>
<rdf:Bag>
<rdf:li>unsorted</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:publisher>
<cc:Agent rdf:about="http://www.openclipart.org/">
<dc:title>Open Clip Art Library, Source: Open Icon Library</dc:title>
</cc:Agent>
</dc:publisher>
<dc:creator>
<cc:Agent>
<dc:title></dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title></dc:title>
</cc:Agent>
</dc:rights>
<dc:date></dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<cc:license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
<dc:language>en</dc:language>
</cc:Work>
<cc:License rdf:about="http://web.resource.org/cc/PublicDomain">
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
<defs id="defs4">
<inkscape:perspective id="perspective10" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" sodipodi:type="inkscape:persp3d"/>
<inkscape:perspective id="perspective2447" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" sodipodi:type="inkscape:persp3d"/>
</defs>
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" gridtolerance="10000" guidetolerance="10" id="base" inkscape:current-layer="layer1" inkscape:cx="135.12026" inkscape:cy="170.7944" inkscape:document-units="px" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="695" inkscape:window-width="1026" inkscape:window-x="14" inkscape:window-y="304" inkscape:zoom="0.49497475" objecttolerance="10" pagecolor="#ffffff" showgrid="false"/>
<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
<path d="M 79.161132,140.51003 L 11.33778,103.91758 L 86.568461,118.27664 L 79.161132,140.51003 z" id="path2453" sodipodi:nodetypes="cccc" style="fill:#c1003f;fill-opacity:1;fill-rule:evenodd;stroke:#c1003f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
<path d="M 89.577687,112.71829 L 48.374422,45.091762 L 106.24417,98.822435 L 89.577687,112.71829 z" id="path2455" sodipodi:nodetypes="cccc" style="fill:#c1003f;fill-opacity:1;fill-rule:evenodd;stroke:#c1003f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
<path d="M 134.02166,93.26409 L 115.50334,16.836839 L 112.72558,95.580067 L 134.02166,93.26409 z" id="path2457" sodipodi:nodetypes="cccc" style="fill:#c1003f;fill-opacity:1;fill-rule:evenodd;stroke:#c1003f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
<path d="M 141.66047,94.42208 L 185.32405,29.178587 L 160.64174,104.38078 L 141.66047,94.42208 z" id="path2459" sodipodi:nodetypes="cccc" style="fill:#c1003f;fill-opacity:1;fill-rule:evenodd;stroke:#c1003f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
<path d="M 177.53971,130.31973 L 166.42872,110.40232 L 234.88038,79.223188 L 177.53971,130.31973 z" id="path2461" sodipodi:nodetypes="cccc" style="fill:#c1003f;fill-opacity:1;fill-rule:evenodd;stroke:#c1003f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
<path d="M 253.54829,146.95649 C 180.91327,134.57788 3.3912247,147.18787 5.0521749,183.5576 C 5.8818386,212.30233 118.37101,219.37995 184.52159,218.6012 C 121.91917,213.36534 74.866933,203.38605 74.078875,185.89383 C 74.927241,155.23904 156.24465,150.16883 253.54829,146.95649 z" id="path3241" sodipodi:nodetypes="ccccc" style="fill:#4a3c7b;fill-opacity:1;fill-rule:evenodd;stroke:#4a3c7b;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { Chart, Settings, AreaSeries } from '@elastic/charts';
import { EuiIcon, EuiTextColor } from '@elastic/eui';
import React, { useContext } from 'react';
import {
EUI_CHARTS_THEME_DARK,
EUI_CHARTS_THEME_LIGHT,
EUI_SPARKLINE_THEME_PARTIAL,
} from '@elastic/eui/dist/eui_charts_theme';
import { ThemeContext } from 'styled-components';
import { NumberOrNull } from '../../../..';
interface Props {
id: string;
value: NumberOrNull;
timeseries: any[];
formatter: (value: NumberOrNull) => string;
color: number;
}
export function MetricWithSparkline({ id, formatter, value, timeseries, color }: Props) {
const themeCTX = useContext(ThemeContext);
const isDarkTheme = (themeCTX && themeCTX.darkMode) || false;
const theme = [
EUI_SPARKLINE_THEME_PARTIAL,
isDarkTheme ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme,
];
const colors = theme[1].colors?.vizColors ?? [];
if (!value) {
return (
<EuiTextColor color="subdued">
<EuiIcon type="visLine" />
&nbsp;N/A
</EuiTextColor>
);
}
return (
<>
<Chart size={{ height: 18, width: 40 }}>
<Settings theme={theme} showLegend={false} tooltip="none" />
<AreaSeries
id={id}
data={timeseries}
xAccessor={'timestamp'}
yAccessors={[id]}
color={colors[color] || '#006BB4'}
/>
</Chart>
&nbsp;
{formatter(value)}
</>
);
}

View file

@ -321,56 +321,18 @@ describe('registerDataHandler', () => {
});
describe('Metrics', () => {
const makeRequestResponse = {
title: 'metrics',
appLink: '/metrics',
sort: () => makeRequest(),
series: [],
};
const makeRequest = async () => {
return makeRequestResponse;
};
registerDataHandler({
appName: 'infra_metrics',
fetchData: async () => {
return {
title: 'metrics',
appLink: '/metrics',
stats: {
hosts: {
label: 'hosts',
type: 'number',
value: 1,
},
cpu: {
label: 'cpu',
type: 'number',
value: 1,
},
memory: {
label: 'memory',
type: 'number',
value: 1,
},
disk: {
label: 'disk',
type: 'number',
value: 1,
},
inboundTraffic: {
label: 'inboundTraffic',
type: 'number',
value: 1,
},
outboundTraffic: {
label: 'outboundTraffic',
type: 'number',
value: 1,
},
},
series: {
inboundTraffic: {
label: 'inbound Traffic',
coordinates: [{ x: 1 }],
},
outboundTraffic: {
label: 'outbound Traffic',
coordinates: [{ x: 1 }],
},
},
};
},
fetchData: makeRequest,
hasData: async () => true,
});
@ -383,52 +345,7 @@ describe('registerDataHandler', () => {
it('returns data when fetchData is called', async () => {
const dataHandler = getDataHandler('infra_metrics');
const response = await dataHandler?.fetchData(params);
expect(response).toEqual({
title: 'metrics',
appLink: '/metrics',
stats: {
hosts: {
label: 'hosts',
type: 'number',
value: 1,
},
cpu: {
label: 'cpu',
type: 'number',
value: 1,
},
memory: {
label: 'memory',
type: 'number',
value: 1,
},
disk: {
label: 'disk',
type: 'number',
value: 1,
},
inboundTraffic: {
label: 'inboundTraffic',
type: 'number',
value: 1,
},
outboundTraffic: {
label: 'outboundTraffic',
type: 'number',
value: 1,
},
},
series: {
inboundTraffic: {
label: 'inbound Traffic',
coordinates: [{ x: 1 }],
},
outboundTraffic: {
label: 'outbound Traffic',
coordinates: [{ x: 1 }],
},
},
});
expect(response).toEqual(makeRequestResponse);
});
it('returns true when hasData is called', async () => {

View file

@ -12,19 +12,13 @@ export const fetchMetricsData: FetchData<MetricsFetchDataResponse> = () => {
};
const response: MetricsFetchDataResponse = {
appLink: '/app/apm',
stats: {
hosts: { value: 11, type: 'number' },
cpu: { value: 0.8, type: 'percent' },
memory: { value: 0.362, type: 'percent' },
},
appLink: '/app/metrics',
sort: async () => response,
series: [],
};
export const emptyResponse: MetricsFetchDataResponse = {
appLink: '/app/apm',
stats: {
hosts: { value: 0, type: 'number' },
cpu: { value: 0, type: 'percent' },
memory: { value: 0, type: 'percent' },
},
appLink: '/app/metrics',
sort: async () => emptyResponse,
series: [],
};

View file

@ -7,7 +7,6 @@
import { ObservabilityApp } from '../../../typings/common';
import { UXMetrics } from '../../components/shared/core_web_vitals';
export interface Stat {
type: 'number' | 'percent' | 'bytesPerSecond';
value: number;
@ -67,12 +66,33 @@ export interface LogsFetchDataResponse extends FetchDataResponse {
series: Record<string, Series & { label: string }>;
}
export type StringOrNull = string | null;
export type NumberOrNull = number | null;
export interface MetricsFetchDataSeries {
id: string;
name: StringOrNull;
platform: StringOrNull;
provider: StringOrNull;
cpu: NumberOrNull;
iowait: NumberOrNull;
load: NumberOrNull;
uptime: NumberOrNull;
rx: NumberOrNull;
tx: NumberOrNull;
timeseries: Array<{
timestamp: number;
cpu: NumberOrNull;
iowait: NumberOrNull;
load: NumberOrNull;
rx: NumberOrNull;
tx: NumberOrNull;
}>;
}
export interface MetricsFetchDataResponse extends FetchDataResponse {
stats: {
hosts: Stat;
cpu: Stat;
memory: Stat;
};
sort: (by: string, direction: string) => Promise<MetricsFetchDataResponse>;
series: MetricsFetchDataSeries[];
}
export interface UptimeFetchDataResponse extends FetchDataResponse {

View file

@ -16652,9 +16652,6 @@
"xpack.observability.overview.logs.subtitle": "毎分のログレート",
"xpack.observability.overview.logs.title": "ログ",
"xpack.observability.overview.metrics.appLink": "アプリで表示",
"xpack.observability.overview.metrics.cpuUsage": "CPU 使用状況",
"xpack.observability.overview.metrics.hosts": "ホスト",
"xpack.observability.overview.metrics.memoryUsage": "メモリー使用状況",
"xpack.observability.overview.metrics.title": "メトリック",
"xpack.observability.overview.uptime.appLink": "アプリで表示",
"xpack.observability.overview.uptime.chart.down": "ダウン",

View file

@ -16878,9 +16878,6 @@
"xpack.observability.overview.logs.subtitle": "每分钟日志速率",
"xpack.observability.overview.logs.title": "日志",
"xpack.observability.overview.metrics.appLink": "在应用中查看",
"xpack.observability.overview.metrics.cpuUsage": "CPU 使用",
"xpack.observability.overview.metrics.hosts": "主机",
"xpack.observability.overview.metrics.memoryUsage": "内存使用",
"xpack.observability.overview.metrics.title": "指标",
"xpack.observability.overview.uptime.appLink": "在应用中查看",
"xpack.observability.overview.uptime.chart.down": "关闭",