mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Infra][ECO] Adding summary API (#194612)](https://github.com/elastic/kibana/pull/194612) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Cauê Marcondes","email":"55978943+cauemarcondes@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-04T08:46:54Z","message":"[Infra][ECO] Adding summary API (#194612)\n\ncloses https://github.com/elastic/kibana/issues/193701\r\n\r\nThis PR does a few things:\r\n- Adds a new API endpoint on infra to fetch an entity summary:\r\n`/api/infra/entities/{entityType}/{entityId}/summary`. It fetches the\r\nlatest EEM index filtering by entity.type(host | container) and\r\ndepending on the entity type host.name or container.id. And it returns\r\nthe following payload:\r\n```\r\n{\r\n \"sourceDataStreams\": [\r\n \"logs\",\r\n \"metrics\"\r\n ],\r\n \"entityId\": \"caues-mbp\",\r\n \"entityType\": \"host\"\r\n}\r\n```\r\n- Fix a problem on the `Service` entity definition removing the\r\n`datastream.type` and moving it to `source_data_stream.type` due to ECS\r\nconflicts.\r\n- Moves some common field definitions to **observability-shared**\r\nplugin, and updated APM and Inventory plugin.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"a91d00731ae732c3bb2d370651048d94dd8adc2b","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-infra_services","v8.16.0"],"title":"[Infra][ECO] Adding summary API","number":194612,"url":"https://github.com/elastic/kibana/pull/194612","mergeCommit":{"message":"[Infra][ECO] Adding summary API (#194612)\n\ncloses https://github.com/elastic/kibana/issues/193701\r\n\r\nThis PR does a few things:\r\n- Adds a new API endpoint on infra to fetch an entity summary:\r\n`/api/infra/entities/{entityType}/{entityId}/summary`. It fetches the\r\nlatest EEM index filtering by entity.type(host | container) and\r\ndepending on the entity type host.name or container.id. And it returns\r\nthe following payload:\r\n```\r\n{\r\n \"sourceDataStreams\": [\r\n \"logs\",\r\n \"metrics\"\r\n ],\r\n \"entityId\": \"caues-mbp\",\r\n \"entityType\": \"host\"\r\n}\r\n```\r\n- Fix a problem on the `Service` entity definition removing the\r\n`datastream.type` and moving it to `source_data_stream.type` due to ECS\r\nconflicts.\r\n- Moves some common field definitions to **observability-shared**\r\nplugin, and updated APM and Inventory plugin.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"a91d00731ae732c3bb2d370651048d94dd8adc2b"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194612","number":194612,"mergeCommit":{"message":"[Infra][ECO] Adding summary API (#194612)\n\ncloses https://github.com/elastic/kibana/issues/193701\r\n\r\nThis PR does a few things:\r\n- Adds a new API endpoint on infra to fetch an entity summary:\r\n`/api/infra/entities/{entityType}/{entityId}/summary`. It fetches the\r\nlatest EEM index filtering by entity.type(host | container) and\r\ndepending on the entity type host.name or container.id. And it returns\r\nthe following payload:\r\n```\r\n{\r\n \"sourceDataStreams\": [\r\n \"logs\",\r\n \"metrics\"\r\n ],\r\n \"entityId\": \"caues-mbp\",\r\n \"entityType\": \"host\"\r\n}\r\n```\r\n- Fix a problem on the `Service` entity definition removing the\r\n`datastream.type` and moving it to `source_data_stream.type` due to ECS\r\nconflicts.\r\n- Moves some common field definitions to **observability-shared**\r\nplugin, and updated APM and Inventory plugin.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"a91d00731ae732c3bb2d370651048d94dd8adc2b"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Cauê Marcondes <55978943+cauemarcondes@users.noreply.github.com>
This commit is contained in:
parent
7e77855c4e
commit
d6f5f34dff
32 changed files with 250 additions and 83 deletions
|
@ -20,7 +20,7 @@ const serviceTransactionFilter = (additionalFilters: string[] = []) => {
|
||||||
|
|
||||||
export const builtInServicesFromLogsEntityDefinition: EntityDefinition =
|
export const builtInServicesFromLogsEntityDefinition: EntityDefinition =
|
||||||
entityDefinitionSchema.parse({
|
entityDefinitionSchema.parse({
|
||||||
version: '0.2.0',
|
version: '0.3.0',
|
||||||
id: `${BUILT_IN_ID_PREFIX}services_from_ecs_data`,
|
id: `${BUILT_IN_ID_PREFIX}services_from_ecs_data`,
|
||||||
name: 'Services from ECS data',
|
name: 'Services from ECS data',
|
||||||
description:
|
description:
|
||||||
|
@ -46,8 +46,15 @@ export const builtInServicesFromLogsEntityDefinition: EntityDefinition =
|
||||||
displayNameTemplate: '{{service.name}}',
|
displayNameTemplate: '{{service.name}}',
|
||||||
metadata: [
|
metadata: [
|
||||||
{ source: '_index', destination: 'sourceIndex' },
|
{ source: '_index', destination: 'sourceIndex' },
|
||||||
|
{
|
||||||
|
source: 'data_stream.type',
|
||||||
|
destination: 'source_data_stream.type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: 'data_stream.dataset',
|
||||||
|
destination: 'source_data_stream.dataset',
|
||||||
|
},
|
||||||
{ source: 'agent.name', aggregation: { type: 'terms', limit: 100 } },
|
{ source: 'agent.name', aggregation: { type: 'terms', limit: 100 } },
|
||||||
'data_stream.type',
|
|
||||||
'service.environment',
|
'service.environment',
|
||||||
'service.name',
|
'service.name',
|
||||||
'service.namespace',
|
'service.namespace',
|
||||||
|
|
|
@ -31,6 +31,7 @@ export async function findEntityDefinitions({
|
||||||
page = 1,
|
page = 1,
|
||||||
perPage = 10,
|
perPage = 10,
|
||||||
includeState = false,
|
includeState = false,
|
||||||
|
type,
|
||||||
}: {
|
}: {
|
||||||
soClient: SavedObjectsClientContract;
|
soClient: SavedObjectsClientContract;
|
||||||
esClient: ElasticsearchClient;
|
esClient: ElasticsearchClient;
|
||||||
|
@ -39,12 +40,14 @@ export async function findEntityDefinitions({
|
||||||
page?: number;
|
page?: number;
|
||||||
perPage?: number;
|
perPage?: number;
|
||||||
includeState?: boolean;
|
includeState?: boolean;
|
||||||
|
type?: string;
|
||||||
}): Promise<EntityDefinition[] | EntityDefinitionWithState[]> {
|
}): Promise<EntityDefinition[] | EntityDefinitionWithState[]> {
|
||||||
const filter = compact([
|
const filter = compact([
|
||||||
typeof builtIn === 'boolean'
|
typeof builtIn === 'boolean'
|
||||||
? `${SO_ENTITY_DEFINITION_TYPE}.attributes.id:(${BUILT_IN_ID_PREFIX}*)`
|
? `${SO_ENTITY_DEFINITION_TYPE}.attributes.id:(${BUILT_IN_ID_PREFIX}*)`
|
||||||
: undefined,
|
: undefined,
|
||||||
id ? `${SO_ENTITY_DEFINITION_TYPE}.attributes.id:(${id})` : undefined,
|
id ? `${SO_ENTITY_DEFINITION_TYPE}.attributes.id:(${id})` : undefined,
|
||||||
|
type ? `${SO_ENTITY_DEFINITION_TYPE}.attributes.type:(${type})` : undefined,
|
||||||
]).join(' AND ');
|
]).join(' AND ');
|
||||||
const response = await soClient.find<EntityDefinition>({
|
const response = await soClient.find<EntityDefinition>({
|
||||||
type: SO_ENTITY_DEFINITION_TYPE,
|
type: SO_ENTITY_DEFINITION_TYPE,
|
||||||
|
|
|
@ -75,11 +75,15 @@ export class EntityClient {
|
||||||
page = 1,
|
page = 1,
|
||||||
perPage = 10,
|
perPage = 10,
|
||||||
includeState = false,
|
includeState = false,
|
||||||
|
type,
|
||||||
|
builtIn,
|
||||||
}: {
|
}: {
|
||||||
id?: string;
|
id?: string;
|
||||||
page?: number;
|
page?: number;
|
||||||
perPage?: number;
|
perPage?: number;
|
||||||
includeState?: boolean;
|
includeState?: boolean;
|
||||||
|
type?: string;
|
||||||
|
builtIn?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const definitions = await findEntityDefinitions({
|
const definitions = await findEntityDefinitions({
|
||||||
esClient: this.options.esClient,
|
esClient: this.options.esClient,
|
||||||
|
@ -88,6 +92,8 @@ export class EntityClient {
|
||||||
perPage,
|
perPage,
|
||||||
id,
|
id,
|
||||||
includeState,
|
includeState,
|
||||||
|
type,
|
||||||
|
builtIn,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { definitions };
|
return { definitions };
|
||||||
|
|
|
@ -5,13 +5,8 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const ENTITY = 'entity';
|
|
||||||
export const LAST_SEEN = 'entity.lastSeenTimestamp';
|
|
||||||
export const FIRST_SEEN = 'entity.firstSeenTimestamp';
|
|
||||||
export const ENTITY_ID = 'entity.id';
|
|
||||||
export const ENTITY_METRICS_LATENCY = 'entity.metrics.latency';
|
export const ENTITY_METRICS_LATENCY = 'entity.metrics.latency';
|
||||||
export const ENTITY_METRICS_LOG_ERROR_RATE = 'entity.metrics.logErrorRate';
|
export const ENTITY_METRICS_LOG_ERROR_RATE = 'entity.metrics.logErrorRate';
|
||||||
export const ENTITY_METRICS_LOG_RATE = 'entity.metrics.logRate';
|
export const ENTITY_METRICS_LOG_RATE = 'entity.metrics.logRate';
|
||||||
export const ENTITY_METRICS_THROUGHPUT = 'entity.metrics.throughput';
|
export const ENTITY_METRICS_THROUGHPUT = 'entity.metrics.throughput';
|
||||||
export const ENTITY_METRICS_FAILED_TRANSACTION_RATE = 'entity.metrics.failedTransactionRate';
|
export const ENTITY_METRICS_FAILED_TRANSACTION_RATE = 'entity.metrics.failedTransactionRate';
|
||||||
export const ENTITY_TYPE = 'entity.type';
|
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||||
import { FIRST_SEEN, LAST_SEEN } from '../../../common/es_fields/entities';
|
import {
|
||||||
|
ENTITY_FIRST_SEEN,
|
||||||
|
ENTITY_LAST_SEEN,
|
||||||
|
} from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
import type { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
import type { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
||||||
import { getEntityLatestServices } from './get_entity_latest_services';
|
import { getEntityLatestServices } from './get_entity_latest_services';
|
||||||
import type { EntityLatestServiceRaw } from './types';
|
import type { EntityLatestServiceRaw } from './types';
|
||||||
|
@ -19,14 +22,14 @@ export function entitiesRangeQuery(start?: number, end?: number): QueryDslQueryC
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
range: {
|
range: {
|
||||||
[LAST_SEEN]: {
|
[ENTITY_LAST_SEEN]: {
|
||||||
gte: start,
|
gte: start,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
range: {
|
range: {
|
||||||
[FIRST_SEEN]: {
|
[ENTITY_FIRST_SEEN]: {
|
||||||
lte: end,
|
lte: end,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,16 +5,18 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { termsQuery, rangeQuery } from '@kbn/observability-plugin/server';
|
import { rangeQuery, termsQuery } from '@kbn/observability-plugin/server';
|
||||||
import { EntityMetrics } from '../../../common/entities/types';
|
|
||||||
import {
|
import {
|
||||||
ENTITY_ID,
|
ENTITY_ID,
|
||||||
|
ENTITY_LAST_SEEN,
|
||||||
|
} from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
|
import { EntityMetrics } from '../../../common/entities/types';
|
||||||
|
import {
|
||||||
ENTITY_METRICS_FAILED_TRANSACTION_RATE,
|
ENTITY_METRICS_FAILED_TRANSACTION_RATE,
|
||||||
ENTITY_METRICS_LATENCY,
|
ENTITY_METRICS_LATENCY,
|
||||||
ENTITY_METRICS_LOG_ERROR_RATE,
|
ENTITY_METRICS_LOG_ERROR_RATE,
|
||||||
ENTITY_METRICS_LOG_RATE,
|
ENTITY_METRICS_LOG_RATE,
|
||||||
ENTITY_METRICS_THROUGHPUT,
|
ENTITY_METRICS_THROUGHPUT,
|
||||||
LAST_SEEN,
|
|
||||||
} from '../../../common/es_fields/entities';
|
} from '../../../common/es_fields/entities';
|
||||||
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
||||||
|
|
||||||
|
@ -39,7 +41,10 @@ export async function getEntityHistoryServicesMetrics({
|
||||||
track_total_hits: false,
|
track_total_hits: false,
|
||||||
query: {
|
query: {
|
||||||
bool: {
|
bool: {
|
||||||
filter: [...rangeQuery(start, end, LAST_SEEN), ...termsQuery(ENTITY_ID, ...entityIds)],
|
filter: [
|
||||||
|
...rangeQuery(start, end, ENTITY_LAST_SEEN),
|
||||||
|
...termsQuery(ENTITY_ID, ...entityIds),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
aggs: {
|
aggs: {
|
||||||
|
|
|
@ -5,20 +5,20 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { termsQuery, rangeQuery } from '@kbn/observability-plugin/server';
|
|
||||||
import { getBucketSize } from '@kbn/apm-data-access-plugin/common';
|
import { getBucketSize } from '@kbn/apm-data-access-plugin/common';
|
||||||
|
import { rangeQuery, termsQuery } from '@kbn/observability-plugin/server';
|
||||||
|
import { ENTITY_LAST_SEEN } from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
import { keyBy } from 'lodash';
|
import { keyBy } from 'lodash';
|
||||||
|
import { SERVICE_NAME } from '../../../common/es_fields/apm';
|
||||||
import {
|
import {
|
||||||
ENTITY_METRICS_FAILED_TRANSACTION_RATE,
|
ENTITY_METRICS_FAILED_TRANSACTION_RATE,
|
||||||
ENTITY_METRICS_LATENCY,
|
ENTITY_METRICS_LATENCY,
|
||||||
ENTITY_METRICS_LOG_ERROR_RATE,
|
ENTITY_METRICS_LOG_ERROR_RATE,
|
||||||
ENTITY_METRICS_LOG_RATE,
|
ENTITY_METRICS_LOG_RATE,
|
||||||
ENTITY_METRICS_THROUGHPUT,
|
ENTITY_METRICS_THROUGHPUT,
|
||||||
LAST_SEEN,
|
|
||||||
} from '../../../common/es_fields/entities';
|
} from '../../../common/es_fields/entities';
|
||||||
import { SERVICE_NAME } from '../../../common/es_fields/apm';
|
|
||||||
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
|
||||||
import { environmentQuery } from '../../../common/utils/environment_query';
|
import { environmentQuery } from '../../../common/utils/environment_query';
|
||||||
|
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
||||||
|
|
||||||
interface Params {
|
interface Params {
|
||||||
entitiesESClient: EntitiesESClient;
|
entitiesESClient: EntitiesESClient;
|
||||||
|
@ -48,7 +48,7 @@ export async function getEntityHistoryServicesTimeseries({
|
||||||
query: {
|
query: {
|
||||||
bool: {
|
bool: {
|
||||||
filter: [
|
filter: [
|
||||||
...rangeQuery(start, end, LAST_SEEN),
|
...rangeQuery(start, end, ENTITY_LAST_SEEN),
|
||||||
...termsQuery(SERVICE_NAME, ...serviceNames),
|
...termsQuery(SERVICE_NAME, ...serviceNames),
|
||||||
...environmentQuery(environment),
|
...environmentQuery(environment),
|
||||||
],
|
],
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
|
|
||||||
import { kqlQuery, termQuery } from '@kbn/observability-plugin/server';
|
import { kqlQuery, termQuery } from '@kbn/observability-plugin/server';
|
||||||
import {
|
import {
|
||||||
AGENT_NAME,
|
ENTITY,
|
||||||
DATA_STEAM_TYPE,
|
ENTITY_TYPE,
|
||||||
SERVICE_ENVIRONMENT,
|
SOURCE_DATA_STREAM_TYPE,
|
||||||
SERVICE_NAME,
|
} from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
} from '../../../common/es_fields/apm';
|
import { AGENT_NAME, SERVICE_ENVIRONMENT, SERVICE_NAME } from '../../../common/es_fields/apm';
|
||||||
import { ENTITY, ENTITY_TYPE } from '../../../common/es_fields/entities';
|
|
||||||
import { environmentQuery } from '../../../common/utils/environment_query';
|
import { environmentQuery } from '../../../common/utils/environment_query';
|
||||||
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client';
|
||||||
import { entitiesRangeQuery } from './get_entities';
|
import { entitiesRangeQuery } from './get_entities';
|
||||||
|
@ -40,7 +39,7 @@ export async function getEntityLatestServices({
|
||||||
body: {
|
body: {
|
||||||
size,
|
size,
|
||||||
track_total_hits: false,
|
track_total_hits: false,
|
||||||
_source: [AGENT_NAME, ENTITY, DATA_STEAM_TYPE, SERVICE_NAME, SERVICE_ENVIRONMENT],
|
_source: [AGENT_NAME, ENTITY, SOURCE_DATA_STREAM_TYPE, SERVICE_NAME, SERVICE_ENVIRONMENT],
|
||||||
query: {
|
query: {
|
||||||
bool: {
|
bool: {
|
||||||
filter: [
|
filter: [
|
||||||
|
|
|
@ -15,7 +15,7 @@ export interface EntityLatestServiceRaw {
|
||||||
agent: {
|
agent: {
|
||||||
name: AgentName[];
|
name: AgentName[];
|
||||||
};
|
};
|
||||||
data_stream: {
|
source_data_stream: {
|
||||||
type: string[];
|
type: string[];
|
||||||
};
|
};
|
||||||
service: {
|
service: {
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'test',
|
environment: 'test',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['metrics', 'logs'] },
|
source_data_stream: { type: ['metrics', 'logs'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -64,7 +64,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'env-service-1',
|
environment: 'env-service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['foo'] },
|
source_data_stream: { type: ['foo'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
||||||
|
@ -85,7 +85,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'env-service-2',
|
environment: 'env-service-2',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['bar'] },
|
source_data_stream: { type: ['bar'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-03-05T10:34:40.810Z',
|
||||||
|
@ -106,7 +106,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'env-service-3',
|
environment: 'env-service-3',
|
||||||
},
|
},
|
||||||
agent: { name: ['java'] },
|
agent: { name: ['java'] },
|
||||||
data_stream: { type: ['baz'] },
|
source_data_stream: { type: ['baz'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -127,7 +127,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'env-service-4',
|
environment: 'env-service-4',
|
||||||
},
|
},
|
||||||
agent: { name: ['java'] },
|
agent: { name: ['java'] },
|
||||||
data_stream: { type: ['baz'] },
|
source_data_stream: { type: ['baz'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -204,7 +204,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'test',
|
environment: 'test',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['metrics', 'logs'] },
|
source_data_stream: { type: ['metrics', 'logs'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -225,7 +225,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'test',
|
environment: 'test',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['metrics', 'logs'] },
|
source_data_stream: { type: ['metrics', 'logs'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -246,7 +246,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'prod',
|
environment: 'prod',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['foo'] },
|
source_data_stream: { type: ['foo'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-23-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-23-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-23-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-23-05T10:34:40.810Z',
|
||||||
|
@ -305,7 +305,7 @@ describe('mergeEntities', () => {
|
||||||
environment: undefined,
|
environment: undefined,
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -348,7 +348,7 @@ describe('mergeEntities', () => {
|
||||||
name: 'service-1',
|
name: 'service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -368,7 +368,7 @@ describe('mergeEntities', () => {
|
||||||
name: 'service-1',
|
name: 'service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -420,7 +420,7 @@ describe('mergeEntities', () => {
|
||||||
name: 'service-1',
|
name: 'service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -463,7 +463,7 @@ describe('mergeEntities', () => {
|
||||||
name: 'service-1',
|
name: 'service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -483,7 +483,7 @@ describe('mergeEntities', () => {
|
||||||
name: 'service-1',
|
name: 'service-1',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: [] },
|
source_data_stream: { type: [] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
@ -536,7 +536,7 @@ describe('mergeEntities', () => {
|
||||||
environment: 'test',
|
environment: 'test',
|
||||||
},
|
},
|
||||||
agent: { name: ['nodejs'] },
|
agent: { name: ['nodejs'] },
|
||||||
data_stream: { type: ['metrics'] },
|
source_data_stream: { type: ['metrics'] },
|
||||||
entity: {
|
entity: {
|
||||||
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
firstSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
lastSeenTimestamp: '2024-06-05T10:34:40.810Z',
|
||||||
|
|
|
@ -53,7 +53,7 @@ function mergeFunc(entity: EntityLatestServiceRaw, existingEntity?: MergedServic
|
||||||
if (!existingEntity) {
|
if (!existingEntity) {
|
||||||
return {
|
return {
|
||||||
...commonEntityFields,
|
...commonEntityFields,
|
||||||
dataStreamTypes: entity.data_stream.type,
|
dataStreamTypes: entity.source_data_stream.type,
|
||||||
environments: compact([entity?.service.environment]),
|
environments: compact([entity?.service.environment]),
|
||||||
metrics: [entity.entity.metrics],
|
metrics: [entity.entity.metrics],
|
||||||
hasLogMetrics,
|
hasLogMetrics,
|
||||||
|
@ -62,7 +62,7 @@ function mergeFunc(entity: EntityLatestServiceRaw, existingEntity?: MergedServic
|
||||||
return {
|
return {
|
||||||
...commonEntityFields,
|
...commonEntityFields,
|
||||||
dataStreamTypes: uniq(
|
dataStreamTypes: uniq(
|
||||||
compact([...(existingEntity?.dataStreamTypes ?? []), ...entity.data_stream.type])
|
compact([...(existingEntity?.dataStreamTypes ?? []), ...entity.source_data_stream.type])
|
||||||
),
|
),
|
||||||
environments: uniq(compact([...existingEntity?.environments, entity?.service.environment])),
|
environments: uniq(compact([...existingEntity?.environments, entity?.service.environment])),
|
||||||
metrics: [...existingEntity?.metrics, entity.entity.metrics],
|
metrics: [...existingEntity?.metrics, entity.entity.metrics],
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
"usageCollection",
|
"usageCollection",
|
||||||
"visTypeTimeseries",
|
"visTypeTimeseries",
|
||||||
"apmDataAccess",
|
"apmDataAccess",
|
||||||
"logsDataAccess"
|
"logsDataAccess",
|
||||||
|
"entityManager"
|
||||||
],
|
],
|
||||||
"optionalPlugins": [
|
"optionalPlugins": [
|
||||||
"spaces",
|
"spaces",
|
||||||
|
|
|
@ -34,6 +34,7 @@ import { initProfilingRoutes } from './routes/profiling';
|
||||||
import { initServicesRoute } from './routes/services';
|
import { initServicesRoute } from './routes/services';
|
||||||
import { initCustomDashboardsRoutes } from './routes/custom_dashboards/custom_dashboards';
|
import { initCustomDashboardsRoutes } from './routes/custom_dashboards/custom_dashboards';
|
||||||
import { InfraBackendLibs } from './lib/infra_types';
|
import { InfraBackendLibs } from './lib/infra_types';
|
||||||
|
import { initEntitiesConfigurationRoutes } from './routes/entities';
|
||||||
|
|
||||||
export const registerRoutes = (libs: InfraBackendLibs) => {
|
export const registerRoutes = (libs: InfraBackendLibs) => {
|
||||||
initIpToHostName(libs);
|
initIpToHostName(libs);
|
||||||
|
@ -63,4 +64,5 @@ export const registerRoutes = (libs: InfraBackendLibs) => {
|
||||||
initProfilingRoutes(libs);
|
initProfilingRoutes(libs);
|
||||||
initServicesRoute(libs);
|
initServicesRoute(libs);
|
||||||
initCustomDashboardsRoutes(libs.framework);
|
initCustomDashboardsRoutes(libs.framework);
|
||||||
|
initEntitiesConfigurationRoutes(libs);
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,6 +39,10 @@ import {
|
||||||
ApmDataAccessPluginStart,
|
ApmDataAccessPluginStart,
|
||||||
} from '@kbn/apm-data-access-plugin/server';
|
} from '@kbn/apm-data-access-plugin/server';
|
||||||
import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/server';
|
import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/server';
|
||||||
|
import type {
|
||||||
|
EntityManagerServerPluginStart,
|
||||||
|
EntityManagerServerPluginSetup,
|
||||||
|
} from '@kbn/entityManager-plugin/server';
|
||||||
|
|
||||||
export interface InfraServerPluginSetupDeps {
|
export interface InfraServerPluginSetupDeps {
|
||||||
alerting: AlertingPluginContract;
|
alerting: AlertingPluginContract;
|
||||||
|
@ -56,6 +60,7 @@ export interface InfraServerPluginSetupDeps {
|
||||||
metricsDataAccess: MetricsDataPluginSetup;
|
metricsDataAccess: MetricsDataPluginSetup;
|
||||||
profilingDataAccess?: ProfilingDataAccessPluginSetup;
|
profilingDataAccess?: ProfilingDataAccessPluginSetup;
|
||||||
apmDataAccess: ApmDataAccessPluginSetup;
|
apmDataAccess: ApmDataAccessPluginSetup;
|
||||||
|
entityManager: EntityManagerServerPluginSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InfraServerPluginStartDeps {
|
export interface InfraServerPluginStartDeps {
|
||||||
|
@ -66,6 +71,7 @@ export interface InfraServerPluginStartDeps {
|
||||||
ruleRegistry: RuleRegistryPluginStartContract;
|
ruleRegistry: RuleRegistryPluginStartContract;
|
||||||
apmDataAccess: ApmDataAccessPluginStart;
|
apmDataAccess: ApmDataAccessPluginStart;
|
||||||
logsDataAccess: LogsDataAccessPluginStart;
|
logsDataAccess: LogsDataAccessPluginStart;
|
||||||
|
entityManager: EntityManagerServerPluginStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CallWithRequestParams extends estypes.RequestBase {
|
export interface CallWithRequestParams extends estypes.RequestBase {
|
||||||
|
|
|
@ -296,6 +296,7 @@ export class InfraServerPlugin
|
||||||
const coreContext = await context.core;
|
const coreContext = await context.core;
|
||||||
const savedObjectsClient = coreContext.savedObjects.client;
|
const savedObjectsClient = coreContext.savedObjects.client;
|
||||||
const uiSettingsClient = coreContext.uiSettings.client;
|
const uiSettingsClient = coreContext.uiSettings.client;
|
||||||
|
const entityManager = await this.libs.plugins.entityManager.start();
|
||||||
|
|
||||||
const mlSystem = plugins.ml?.mlSystemProvider(request, savedObjectsClient);
|
const mlSystem = plugins.ml?.mlSystemProvider(request, savedObjectsClient);
|
||||||
const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider(
|
const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider(
|
||||||
|
@ -317,6 +318,7 @@ export class InfraServerPlugin
|
||||||
savedObjectsClient,
|
savedObjectsClient,
|
||||||
uiSettingsClient,
|
uiSettingsClient,
|
||||||
getMetricsIndices,
|
getMetricsIndices,
|
||||||
|
entityManager,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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 { type ObservabilityElasticsearchClient } from '@kbn/observability-utils/es/client/create_observability_es_client';
|
||||||
|
import { esqlResultToPlainObjects } from '@kbn/observability-utils/es/utils/esql_result_to_plain_objects';
|
||||||
|
import { ENTITY_LATEST, EntityDefinition, entitiesAliasPattern } from '@kbn/entities-schema';
|
||||||
|
import { type EntityDefinitionWithState } from '@kbn/entityManager-plugin/server/lib/entities/types';
|
||||||
|
import {
|
||||||
|
ENTITY_TYPE,
|
||||||
|
SOURCE_DATA_STREAM_TYPE,
|
||||||
|
} from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
|
|
||||||
|
const ENTITIES_LATEST_ALIAS = entitiesAliasPattern({
|
||||||
|
type: '*',
|
||||||
|
dataset: ENTITY_LATEST,
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Entity {
|
||||||
|
[SOURCE_DATA_STREAM_TYPE]: string | string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLatestEntity({
|
||||||
|
inventoryEsClient,
|
||||||
|
entityId,
|
||||||
|
entityType,
|
||||||
|
entityDefinitions,
|
||||||
|
}: {
|
||||||
|
inventoryEsClient: ObservabilityElasticsearchClient;
|
||||||
|
entityType: 'host' | 'container';
|
||||||
|
entityId: string;
|
||||||
|
entityDefinitions: EntityDefinition[] | EntityDefinitionWithState[];
|
||||||
|
}) {
|
||||||
|
const hostOrContainerIdentityField = entityDefinitions[0]?.identityFields?.[0]?.field;
|
||||||
|
if (hostOrContainerIdentityField === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const latestEntitiesEsqlResponse = await inventoryEsClient.esql('get_latest_entities', {
|
||||||
|
query: `FROM ${ENTITIES_LATEST_ALIAS}
|
||||||
|
| WHERE ${ENTITY_TYPE} == "${entityType}"
|
||||||
|
| WHERE ${hostOrContainerIdentityField} == "${entityId}"
|
||||||
|
| KEEP ${SOURCE_DATA_STREAM_TYPE}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return esqlResultToPlainObjects<Entity>(latestEntitiesEsqlResponse)[0];
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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 { schema } from '@kbn/config-schema';
|
||||||
|
import { METRICS_APP_ID } from '@kbn/deeplinks-observability/constants';
|
||||||
|
import { SOURCE_DATA_STREAM_TYPE } from '@kbn/observability-shared-plugin/common/field_names/elasticsearch';
|
||||||
|
import { createObservabilityEsClient } from '@kbn/observability-utils/es/client/create_observability_es_client';
|
||||||
|
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||||
|
import { getLatestEntity } from './get_latest_entity';
|
||||||
|
|
||||||
|
export const initEntitiesConfigurationRoutes = (libs: InfraBackendLibs) => {
|
||||||
|
const { framework, logger } = libs;
|
||||||
|
|
||||||
|
framework.registerRoute(
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
path: '/api/infra/entities/{entityType}/{entityId}/summary',
|
||||||
|
validate: {
|
||||||
|
params: schema.object({
|
||||||
|
entityType: schema.oneOf([schema.literal('host'), schema.literal('container')]),
|
||||||
|
entityId: schema.string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
access: 'internal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async (requestContext, request, response) => {
|
||||||
|
const { entityId, entityType } = request.params;
|
||||||
|
const coreContext = await requestContext.core;
|
||||||
|
const infraContext = await requestContext.infra;
|
||||||
|
const entityManager = await infraContext.entityManager.getScopedClient({ request });
|
||||||
|
|
||||||
|
const client = createObservabilityEsClient({
|
||||||
|
client: coreContext.elasticsearch.client.asCurrentUser,
|
||||||
|
logger,
|
||||||
|
plugin: `@kbn/${METRICS_APP_ID}-plugin`,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Only fetch built in definitions
|
||||||
|
const { definitions } = await entityManager.getEntityDefinitions({
|
||||||
|
builtIn: true,
|
||||||
|
type: entityType,
|
||||||
|
});
|
||||||
|
if (definitions.length === 0) {
|
||||||
|
return response.ok({
|
||||||
|
body: { sourceDataStreams: [], entityId, entityType },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const entity = await getLatestEntity({
|
||||||
|
inventoryEsClient: client,
|
||||||
|
entityId,
|
||||||
|
entityType,
|
||||||
|
entityDefinitions: definitions,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.ok({
|
||||||
|
body: {
|
||||||
|
sourceDataStreams: [entity?.[SOURCE_DATA_STREAM_TYPE] || []].flat() as string[],
|
||||||
|
entityId,
|
||||||
|
entityType,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return response.customError({
|
||||||
|
statusCode: error.statusCode ?? 500,
|
||||||
|
body: {
|
||||||
|
message: error.message ?? 'An unexpected error occurred',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
|
@ -13,6 +13,7 @@ import type {
|
||||||
} from '@kbn/core/server';
|
} from '@kbn/core/server';
|
||||||
import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server';
|
import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server';
|
||||||
import type { MlPluginSetup } from '@kbn/ml-plugin/server';
|
import type { MlPluginSetup } from '@kbn/ml-plugin/server';
|
||||||
|
import type { EntityManagerServerPluginStart } from '@kbn/entityManager-plugin/server';
|
||||||
import { InfraServerPluginStartDeps } from './lib/adapters/framework';
|
import { InfraServerPluginStartDeps } from './lib/adapters/framework';
|
||||||
import { InventoryViewsServiceSetup, InventoryViewsServiceStart } from './services/inventory_views';
|
import { InventoryViewsServiceSetup, InventoryViewsServiceStart } from './services/inventory_views';
|
||||||
import {
|
import {
|
||||||
|
@ -45,6 +46,7 @@ export interface InfraRequestHandlerContext {
|
||||||
savedObjectsClient: SavedObjectsClientContract;
|
savedObjectsClient: SavedObjectsClientContract;
|
||||||
uiSettingsClient: IUiSettingsClient;
|
uiSettingsClient: IUiSettingsClient;
|
||||||
getMetricsIndices: () => Promise<string>;
|
getMetricsIndices: () => Promise<string>;
|
||||||
|
entityManager: EntityManagerServerPluginStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -109,7 +109,10 @@
|
||||||
"@kbn/core-analytics-browser",
|
"@kbn/core-analytics-browser",
|
||||||
"@kbn/observability-alerting-rule-utils",
|
"@kbn/observability-alerting-rule-utils",
|
||||||
"@kbn/core-application-browser",
|
"@kbn/core-application-browser",
|
||||||
"@kbn/shared-ux-page-no-data-types"
|
"@kbn/shared-ux-page-no-data-types",
|
||||||
|
"@kbn/entityManager-plugin",
|
||||||
|
"@kbn/observability-utils",
|
||||||
|
"@kbn/entities-schema"
|
||||||
],
|
],
|
||||||
"exclude": ["target/**/*"]
|
"exclude": ["target/**/*"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,24 +4,22 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import * as t from 'io-ts';
|
|
||||||
import { ENTITY_LATEST, entitiesAliasPattern } from '@kbn/entities-schema';
|
import { ENTITY_LATEST, entitiesAliasPattern } from '@kbn/entities-schema';
|
||||||
import { isRight } from 'fp-ts/lib/Either';
|
|
||||||
import {
|
import {
|
||||||
SERVICE_ENVIRONMENT,
|
|
||||||
SERVICE_NAME,
|
|
||||||
CONTAINER_ID,
|
CONTAINER_ID,
|
||||||
HOST_NAME,
|
HOST_NAME,
|
||||||
AGENT_NAME,
|
AGENT_NAME,
|
||||||
CLOUD_PROVIDER,
|
CLOUD_PROVIDER,
|
||||||
} from '@kbn/observability-shared-plugin/common';
|
|
||||||
import {
|
|
||||||
ENTITY_DEFINITION_ID,
|
ENTITY_DEFINITION_ID,
|
||||||
ENTITY_DISPLAY_NAME,
|
ENTITY_DISPLAY_NAME,
|
||||||
ENTITY_ID,
|
ENTITY_ID,
|
||||||
ENTITY_LAST_SEEN,
|
ENTITY_LAST_SEEN,
|
||||||
ENTITY_TYPE,
|
ENTITY_TYPE,
|
||||||
} from './es_fields/entities';
|
SERVICE_ENVIRONMENT,
|
||||||
|
SERVICE_NAME,
|
||||||
|
} from '@kbn/observability-shared-plugin/common';
|
||||||
|
import { isRight } from 'fp-ts/lib/Either';
|
||||||
|
import * as t from 'io-ts';
|
||||||
|
|
||||||
export const entityTypeRt = t.union([
|
export const entityTypeRt = t.union([
|
||||||
t.literal('service'),
|
t.literal('service'),
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const ENTITY_LAST_SEEN = 'entity.lastSeenTimestamp';
|
|
||||||
export const ENTITY_ID = 'entity.id';
|
|
||||||
export const ENTITY_TYPE = 'entity.type';
|
|
||||||
export const ENTITY_DISPLAY_NAME = 'entity.displayName';
|
|
||||||
export const ENTITY_DEFINITION_ID = 'entity.definitionId';
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
||||||
import { render, fireEvent, screen } from '@testing-library/react';
|
import { render, fireEvent, screen } from '@testing-library/react';
|
||||||
import { BadgeFilterWithPopover } from '.';
|
import { BadgeFilterWithPopover } from '.';
|
||||||
import { EuiThemeProvider, copyToClipboard } from '@elastic/eui';
|
import { EuiThemeProvider, copyToClipboard } from '@elastic/eui';
|
||||||
import { ENTITY_TYPE } from '../../../common/es_fields/entities';
|
import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common';
|
||||||
|
|
||||||
jest.mock('@elastic/eui', () => ({
|
jest.mock('@elastic/eui', () => ({
|
||||||
...jest.requireActual('@elastic/eui'),
|
...jest.requireActual('@elastic/eui'),
|
||||||
|
|
|
@ -9,9 +9,9 @@ import { EuiDataGridSorting, EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic
|
||||||
import { Meta, Story } from '@storybook/react';
|
import { Meta, Story } from '@storybook/react';
|
||||||
import { orderBy } from 'lodash';
|
import { orderBy } from 'lodash';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
|
import { ENTITY_LAST_SEEN, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common';
|
||||||
import { EntitiesGrid } from '.';
|
import { EntitiesGrid } from '.';
|
||||||
import { EntityType } from '../../../common/entities';
|
import { EntityType } from '../../../common/entities';
|
||||||
import { ENTITY_LAST_SEEN, ENTITY_TYPE } from '../../../common/es_fields/entities';
|
|
||||||
import { entitiesMock } from './mock/entities_mock';
|
import { entitiesMock } from './mock/entities_mock';
|
||||||
|
|
||||||
const stories: Meta<{}> = {
|
const stories: Meta<{}> = {
|
||||||
|
|
|
@ -11,10 +11,11 @@ import {
|
||||||
AssetDetailsLocatorParams,
|
AssetDetailsLocatorParams,
|
||||||
ASSET_DETAILS_LOCATOR_ID,
|
ASSET_DETAILS_LOCATOR_ID,
|
||||||
ServiceOverviewParams,
|
ServiceOverviewParams,
|
||||||
|
ENTITY_TYPE,
|
||||||
|
ENTITY_DISPLAY_NAME,
|
||||||
} from '@kbn/observability-shared-plugin/common';
|
} from '@kbn/observability-shared-plugin/common';
|
||||||
import { useKibana } from '../../../hooks/use_kibana';
|
import { useKibana } from '../../../hooks/use_kibana';
|
||||||
import { EntityIcon } from '../../entity_icon';
|
import { EntityIcon } from '../../entity_icon';
|
||||||
import { ENTITY_DISPLAY_NAME, ENTITY_TYPE } from '../../../../common/es_fields/entities';
|
|
||||||
import { Entity } from '../../../../common/entities';
|
import { Entity } from '../../../../common/entities';
|
||||||
import { parseServiceParams } from '../../../utils/parse_service_params';
|
import { parseServiceParams } from '../../../utils/parse_service_params';
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,16 @@ import { i18n } from '@kbn/i18n';
|
||||||
import { FormattedDate, FormattedMessage, FormattedTime } from '@kbn/i18n-react';
|
import { FormattedDate, FormattedMessage, FormattedTime } from '@kbn/i18n-react';
|
||||||
import { last } from 'lodash';
|
import { last } from 'lodash';
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import type { EntityType } from '../../../common/entities';
|
|
||||||
import {
|
import {
|
||||||
ENTITY_DISPLAY_NAME,
|
ENTITY_DISPLAY_NAME,
|
||||||
ENTITY_LAST_SEEN,
|
ENTITY_LAST_SEEN,
|
||||||
ENTITY_TYPE,
|
ENTITY_TYPE,
|
||||||
} from '../../../common/es_fields/entities';
|
} from '@kbn/observability-shared-plugin/common';
|
||||||
import type { APIReturnType } from '../../api';
|
import { APIReturnType } from '../../api';
|
||||||
import { getEntityTypeLabel } from '../../utils/get_entity_type_label';
|
|
||||||
import { BadgeFilterWithPopover } from '../badge_filter_with_popover';
|
import { BadgeFilterWithPopover } from '../badge_filter_with_popover';
|
||||||
import { EntityName } from './entity_name';
|
import { EntityName } from './entity_name';
|
||||||
|
import { EntityType } from '../../../common/entities';
|
||||||
|
import { getEntityTypeLabel } from '../../utils/get_entity_type_label';
|
||||||
|
|
||||||
type InventoryEntitiesAPIReturnType = APIReturnType<'GET /internal/inventory/entities'>;
|
type InventoryEntitiesAPIReturnType = APIReturnType<'GET /internal/inventory/entities'>;
|
||||||
type LatestEntities = InventoryEntitiesAPIReturnType['entities'];
|
type LatestEntities = InventoryEntitiesAPIReturnType['entities'];
|
||||||
|
@ -147,7 +147,7 @@ export function EntitiesGrid({
|
||||||
const columnEntityTableId = columnId as EntityColumnIds;
|
const columnEntityTableId = columnId as EntityColumnIds;
|
||||||
switch (columnEntityTableId) {
|
switch (columnEntityTableId) {
|
||||||
case ENTITY_TYPE:
|
case ENTITY_TYPE:
|
||||||
const entityType = entity[columnEntityTableId] as EntityType;
|
const entityType = entity[columnEntityTableId];
|
||||||
return (
|
return (
|
||||||
<BadgeFilterWithPopover
|
<BadgeFilterWithPopover
|
||||||
field={ENTITY_TYPE}
|
field={ENTITY_TYPE}
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AGENT_NAME, CLOUD_PROVIDER } from '@kbn/observability-shared-plugin/common';
|
import { AGENT_NAME, CLOUD_PROVIDER, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common';
|
||||||
import { type CloudProvider, CloudProviderIcon, AgentIcon } from '@kbn/custom-icons';
|
import { type CloudProvider, CloudProviderIcon, AgentIcon } from '@kbn/custom-icons';
|
||||||
import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';
|
import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';
|
||||||
import type { AgentName } from '@kbn/elastic-agent-utils';
|
import type { AgentName } from '@kbn/elastic-agent-utils';
|
||||||
import { euiThemeVars } from '@kbn/ui-theme';
|
import { euiThemeVars } from '@kbn/ui-theme';
|
||||||
import { ENTITY_TYPE } from '../../../common/es_fields/entities';
|
|
||||||
import type { Entity } from '../../../common/entities';
|
import type { Entity } from '../../../common/entities';
|
||||||
|
|
||||||
interface EntityIconProps {
|
interface EntityIconProps {
|
||||||
|
|
|
@ -5,22 +5,22 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useMemo } from 'react';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
|
||||||
import { EuiButton } from '@elastic/eui';
|
import { EuiButton } from '@elastic/eui';
|
||||||
import { DataView } from '@kbn/data-views-plugin/public';
|
import { DataView } from '@kbn/data-views-plugin/public';
|
||||||
import { buildPhrasesFilter, PhrasesFilter } from '@kbn/es-query';
|
import { buildPhrasesFilter, PhrasesFilter } from '@kbn/es-query';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
import { useKibana } from '../../hooks/use_kibana';
|
|
||||||
import {
|
import {
|
||||||
ENTITY_DEFINITION_ID,
|
ENTITY_DEFINITION_ID,
|
||||||
ENTITY_DISPLAY_NAME,
|
ENTITY_DISPLAY_NAME,
|
||||||
ENTITY_LAST_SEEN,
|
ENTITY_LAST_SEEN,
|
||||||
ENTITY_TYPE,
|
ENTITY_TYPE,
|
||||||
} from '../../../common/es_fields/entities';
|
} from '@kbn/observability-shared-plugin/common';
|
||||||
import { EntityColumnIds } from '../entities_grid';
|
|
||||||
import { defaultEntityDefinitions } from '../../../common/entities';
|
import { defaultEntityDefinitions } from '../../../common/entities';
|
||||||
import { useInventoryParams } from '../../hooks/use_inventory_params';
|
import { useInventoryParams } from '../../hooks/use_inventory_params';
|
||||||
|
import { useKibana } from '../../hooks/use_kibana';
|
||||||
|
import { EntityColumnIds } from '../entities_grid';
|
||||||
|
|
||||||
const ACTIVE_COLUMNS: EntityColumnIds[] = [ENTITY_DISPLAY_NAME, ENTITY_TYPE, ENTITY_LAST_SEEN];
|
const ACTIVE_COLUMNS: EntityColumnIds[] = [ENTITY_DISPLAY_NAME, ENTITY_TYPE, ENTITY_LAST_SEEN];
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { toNumberRt } from '@kbn/io-ts-utils';
|
||||||
import { Outlet, createRouter } from '@kbn/typed-react-router-config';
|
import { Outlet, createRouter } from '@kbn/typed-react-router-config';
|
||||||
import * as t from 'io-ts';
|
import * as t from 'io-ts';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ENTITY_LAST_SEEN } from '../../common/es_fields/entities';
|
import { ENTITY_LAST_SEEN } from '@kbn/observability-shared-plugin/common';
|
||||||
import { InventoryPageTemplate } from '../components/inventory_page_template';
|
import { InventoryPageTemplate } from '../components/inventory_page_template';
|
||||||
import { InventoryPage } from '../pages/inventory_page';
|
import { InventoryPage } from '../pages/inventory_page';
|
||||||
import { entityTypesRt } from '../../common/entities';
|
import { entityTypesRt } from '../../common/entities';
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { type ObservabilityElasticsearchClient } from '@kbn/observability-utils/es/client/create_observability_es_client';
|
import { type ObservabilityElasticsearchClient } from '@kbn/observability-utils/es/client/create_observability_es_client';
|
||||||
|
import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common';
|
||||||
import { ENTITIES_LATEST_ALIAS, EntityType } from '../../../common/entities';
|
import { ENTITIES_LATEST_ALIAS, EntityType } from '../../../common/entities';
|
||||||
import { ENTITY_TYPE } from '../../../common/es_fields/entities';
|
|
||||||
import { getEntityDefinitionIdWhereClause, getEntityTypesWhereClause } from './query_helper';
|
import { getEntityDefinitionIdWhereClause, getEntityTypesWhereClause } from './query_helper';
|
||||||
|
|
||||||
export async function getEntityTypes({
|
export async function getEntityTypes({
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ENTITY_DEFINITION_ID, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common';
|
||||||
import { EntityType, defaultEntityTypes, defaultEntityDefinitions } from '../../../common/entities';
|
import { EntityType, defaultEntityTypes, defaultEntityDefinitions } from '../../../common/entities';
|
||||||
import { ENTITY_DEFINITION_ID, ENTITY_TYPE } from '../../../common/es_fields/entities';
|
|
||||||
|
|
||||||
export const getEntityTypesWhereClause = (entityTypes: EntityType[] = defaultEntityTypes) =>
|
export const getEntityTypesWhereClause = (entityTypes: EntityType[] = defaultEntityTypes) =>
|
||||||
`WHERE ${ENTITY_TYPE} IN (${entityTypes.map((entityType) => `"${entityType}"`).join()})`;
|
`WHERE ${ENTITY_TYPE} IN (${entityTypes.map((entityType) => `"${entityType}"`).join()})`;
|
||||||
|
|
|
@ -145,3 +145,12 @@ export const PROFILE_ALLOC_OBJECTS = 'profile.alloc_objects.count';
|
||||||
export const PROFILE_ALLOC_SPACE = 'profile.alloc_space.bytes';
|
export const PROFILE_ALLOC_SPACE = 'profile.alloc_space.bytes';
|
||||||
export const PROFILE_INUSE_OBJECTS = 'profile.inuse_objects.count';
|
export const PROFILE_INUSE_OBJECTS = 'profile.inuse_objects.count';
|
||||||
export const PROFILE_INUSE_SPACE = 'profile.inuse_space.bytes';
|
export const PROFILE_INUSE_SPACE = 'profile.inuse_space.bytes';
|
||||||
|
|
||||||
|
export const ENTITY = 'entity';
|
||||||
|
export const ENTITY_ID = 'entity.id';
|
||||||
|
export const ENTITY_TYPE = 'entity.type';
|
||||||
|
export const ENTITY_LAST_SEEN = 'entity.lastSeenTimestamp';
|
||||||
|
export const ENTITY_FIRST_SEEN = 'entity.firstSeenTimestamp';
|
||||||
|
export const ENTITY_DISPLAY_NAME = 'entity.displayName';
|
||||||
|
export const ENTITY_DEFINITION_ID = 'entity.definitionId';
|
||||||
|
export const SOURCE_DATA_STREAM_TYPE = 'source_data_stream.type';
|
||||||
|
|
|
@ -128,6 +128,14 @@ export {
|
||||||
PROFILE_ALLOC_SPACE,
|
PROFILE_ALLOC_SPACE,
|
||||||
PROFILE_INUSE_OBJECTS,
|
PROFILE_INUSE_OBJECTS,
|
||||||
PROFILE_INUSE_SPACE,
|
PROFILE_INUSE_SPACE,
|
||||||
|
ENTITY,
|
||||||
|
ENTITY_DEFINITION_ID,
|
||||||
|
ENTITY_DISPLAY_NAME,
|
||||||
|
ENTITY_FIRST_SEEN,
|
||||||
|
ENTITY_ID,
|
||||||
|
ENTITY_LAST_SEEN,
|
||||||
|
ENTITY_TYPE,
|
||||||
|
SOURCE_DATA_STREAM_TYPE,
|
||||||
} from './field_names/elasticsearch';
|
} from './field_names/elasticsearch';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue