View job
@@ -140,9 +141,9 @@ export default class DynamicBaselineFlyout extends Component {
iconType="check"
>
- There is currently a job running for {serviceName} ({
- transactionType
- }).{' '}
+ There is currently a job running for {serviceName} (
+ {transactionType}
+ ).{' '}
View existing job
diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/List/ImpactTooltip.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/List/ImpactTooltip.js
index 5a2528818ce31..594e564cf47d9 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionOverview/List/ImpactTooltip.js
+++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/List/ImpactTooltip.js
@@ -22,7 +22,9 @@ const ImpactTooltip = () => (
trigger="hover"
overlay={
- Impact shows the most used and
slowest endpoints in your service.
+ Impact shows the most used and
+
+ slowest endpoints in your service.
}
>
diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.js
index b815424fc418a..d96243e90e969 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.js
+++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.js
@@ -21,6 +21,7 @@ function mapStateToProps(state = {}) {
const mapDispatchToProps = {};
-export default connect(mapStateToProps, mapDispatchToProps)(
- TransactionOverview
-);
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TransactionOverview);
diff --git a/x-pack/plugins/apm/public/components/shared/ConnectRouterToRedux/index.js b/x-pack/plugins/apm/public/components/shared/ConnectRouterToRedux/index.js
index cc4796b400fc4..306fbce7eb19d 100644
--- a/x-pack/plugins/apm/public/components/shared/ConnectRouterToRedux/index.js
+++ b/x-pack/plugins/apm/public/components/shared/ConnectRouterToRedux/index.js
@@ -11,4 +11,7 @@ import { updateLocation } from '../../../store/location';
const mapDispatchToProps = {
updateLocation
};
-export default connect(null, mapDispatchToProps)(view);
+export default connect(
+ null,
+ mapDispatchToProps
+)(view);
diff --git a/x-pack/plugins/apm/public/components/shared/TabNavigation/index.js b/x-pack/plugins/apm/public/components/shared/TabNavigation/index.js
index 005d23471403b..c8e09caf23d81 100644
--- a/x-pack/plugins/apm/public/components/shared/TabNavigation/index.js
+++ b/x-pack/plugins/apm/public/components/shared/TabNavigation/index.js
@@ -17,4 +17,7 @@ function mapStateToProps(state = {}) {
}
const mapDispatchToProps = {};
-export default connect(mapStateToProps, mapDispatchToProps)(TabNavigation);
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TabNavigation);
diff --git a/x-pack/plugins/apm/public/components/shared/TabNavigation/view.js b/x-pack/plugins/apm/public/components/shared/TabNavigation/view.js
index 284b66adde4ca..6ff6201419f59 100644
--- a/x-pack/plugins/apm/public/components/shared/TabNavigation/view.js
+++ b/x-pack/plugins/apm/public/components/shared/TabNavigation/view.js
@@ -80,7 +80,8 @@ function TabNavigation({ urlParams, location }) {
- Transaction type:
+ Transaction type:
+
{label}
}
diff --git a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/Legends.js b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/Legends.js
index a9fdefc850f83..0a6d84079a66f 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/Legends.js
+++ b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/Legends.js
@@ -57,7 +57,12 @@ function MoreSeries({ hiddenSeriesCount }) {
return null;
}
- return (+{hiddenSeriesCount});
+ return (
+
+ (+
+ {hiddenSeriesCount})
+
+ );
}
export default function Legends({
diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.js b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.js
index 51dd9ee6d17f9..6b1ea039f6cda 100644
--- a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.js
+++ b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.js
@@ -15,7 +15,10 @@ const INITIAL_DATA = [];
const withInitialData = createInitialDataSelector(INITIAL_DATA);
const getRelativeImpact = (impact, impactMin, impactMax) =>
- Math.max((impact - impactMin) / Math.max(impactMax - impactMin, 1) * 100, 1);
+ Math.max(
+ ((impact - impactMin) / Math.max(impactMax - impactMin, 1)) * 100,
+ 1
+ );
function getWithRelativeImpact(items) {
const impacts = items.map(({ impact }) => impact);
diff --git a/x-pack/plugins/apm/public/utils/url.js b/x-pack/plugins/apm/public/utils/url.js
index d17360b70e742..5a9f21c3b2560 100644
--- a/x-pack/plugins/apm/public/utils/url.js
+++ b/x-pack/plugins/apm/public/utils/url.js
@@ -125,7 +125,10 @@ export function KibanaLinkComponent({
return ;
}
-const withLocation = connect(({ location }) => ({ location }), {});
+const withLocation = connect(
+ ({ location }) => ({ location }),
+ {}
+);
export const RelativeLink = withLocation(RelativeLinkComponent);
export const KibanaLink = withLocation(KibanaLinkComponent);
diff --git a/yarn.lock b/yarn.lock
index 79181062e34c9..403280da7edb7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10822,8 +10822,8 @@ preserve@^0.2.0:
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier@^1.12.1:
- version "1.12.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325"
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.0.tgz#847c235522035fd988100f1f43cf20a7d24f9372"
pretty-format@^22.4.3:
version "22.4.3"
From fff0713c1e64ffb5942af49ddb3585083e755ce5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Tue, 31 Jul 2018 12:05:32 +0200
Subject: [PATCH 2/6] Apply new prettier formatting
---
.../logging/log_minimap/log_minimap.tsx | 2 +-
.../logging_legacy/state/entries/epics.ts | 5 +-
.../nodes/lib/create_partition_bodies.ts | 27 +++++-----
.../lib/adapters/nodes/lib/create_query.ts | 50 +++++++++++--------
.../lib/adapters/nodes/lib/process_nodes.ts | 8 +--
.../infra/server/lib/domains/fields_domain.ts | 24 +++++----
6 files changed, 66 insertions(+), 50 deletions(-)
diff --git a/x-pack/plugins/infra/public/components/logging/log_minimap/log_minimap.tsx b/x-pack/plugins/infra/public/components/logging/log_minimap/log_minimap.tsx
index 12323f90eb2ff..99255410e6519 100644
--- a/x-pack/plugins/infra/public/components/logging/log_minimap/log_minimap.tsx
+++ b/x-pack/plugins/infra/public/components/logging/log_minimap/log_minimap.tsx
@@ -82,7 +82,7 @@ export class LogMinimap extends React.Component {
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
index 6463319c1c556..34f7bc140cfd3 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
@@ -107,7 +107,10 @@ export const createSummaryEpic = (): Epic<
)
)
),
- action$.pipe(filter(() => false /* TODO: filter jumpToEnd */), map(() => ({ isJump: true })))
+ action$.pipe(
+ filter(() => false /* TODO: filter jumpToEnd */),
+ map(() => ({ isJump: true }))
+ )
).pipe(
map(({ isJump }) => ({
isJump,
diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_partition_bodies.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_partition_bodies.ts
index 921bc27c4b0fd..dc291b9293827 100644
--- a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_partition_bodies.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_partition_bodies.ts
@@ -22,17 +22,20 @@ export function createPartitionBodies(
const { sourceConfiguration }: InfraNodeRequestOptions = nodeOptions;
const bodies: InfraESMSearchBody[] = [];
const numberOfPartitions: number = Math.ceil(totalNodes / NODE_REQUEST_PARTITION_SIZE);
- times(numberOfPartitions, (partitionId: number): void => {
- const processorOptions: InfraProcesorRequestOptions = {
- nodeField,
- nodeOptions,
- numberOfPartitions,
- partitionId,
- };
- bodies.push({
- index: [sourceConfiguration.logAlias, sourceConfiguration.metricAlias],
- });
- bodies.push(createNodeRequestBody(processorOptions));
- });
+ times(
+ numberOfPartitions,
+ (partitionId: number): void => {
+ const processorOptions: InfraProcesorRequestOptions = {
+ nodeField,
+ nodeOptions,
+ numberOfPartitions,
+ partitionId,
+ };
+ bodies.push({
+ index: [sourceConfiguration.logAlias, sourceConfiguration.metricAlias],
+ });
+ bodies.push(createNodeRequestBody(processorOptions));
+ }
+ );
return bodies;
}
diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_query.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_query.ts
index 0257798c84ebd..3c4d077598843 100644
--- a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_query.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/create_query.ts
@@ -40,32 +40,38 @@ export function createQuery(options: InfraNodeRequestOptions): InfraESQuery {
filterClause.push(rangeFilter);
if (groupBy) {
- groupBy.forEach((group: InfraPathInput): void => {
- if (isGroupByTerms(group) && group.field) {
- const inputFilter: InfraFilterInput = {
- type: InfraFilterType.exists,
- value: group.field,
- };
- mustClause.push(convertInputFilterToESQuery(inputFilter));
+ groupBy.forEach(
+ (group: InfraPathInput): void => {
+ if (isGroupByTerms(group) && group.field) {
+ const inputFilter: InfraFilterInput = {
+ type: InfraFilterType.exists,
+ value: group.field,
+ };
+ mustClause.push(convertInputFilterToESQuery(inputFilter));
+ }
+ if (isGroupByFilters(group) && group.filters) {
+ group.filters!.forEach(
+ (groupFilter: InfraPathFilterInput | null): void => {
+ if (groupFilter != null && groupFilter.query) {
+ const inputFilter: InfraFilterInput = {
+ type: InfraFilterType.query_string,
+ value: groupFilter.query,
+ };
+ shouldClause.push(convertInputFilterToESQuery(inputFilter));
+ }
+ }
+ );
+ }
}
- if (isGroupByFilters(group) && group.filters) {
- group.filters!.forEach((groupFilter: InfraPathFilterInput | null): void => {
- if (groupFilter != null && groupFilter.query) {
- const inputFilter: InfraFilterInput = {
- type: InfraFilterType.query_string,
- value: groupFilter.query,
- };
- shouldClause.push(convertInputFilterToESQuery(inputFilter));
- }
- });
- }
- });
+ );
}
if (filters) {
- filters.forEach((filter: InfraFilterInput): void => {
- mustClause.push(convertInputFilterToESQuery(filter));
- });
+ filters.forEach(
+ (filter: InfraFilterInput): void => {
+ mustClause.push(convertInputFilterToESQuery(filter));
+ }
+ );
}
const query: InfraESBoolQuery = {
diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/process_nodes.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/process_nodes.ts
index 5f77be348d8b3..63467bb43e3d6 100644
--- a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/process_nodes.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/process_nodes.ts
@@ -17,9 +17,11 @@ export function processNodes(options: InfraNodeRequestOptions, nodes: any[]): In
if (options.groupBy.length === 0) {
// If there are NO group by options then we need to return a
// nodes only response
- const nodeResults: InfraNode[] = nodes.map((node: InfraBucket): InfraNode => {
- return createNodeItem(options, node, node);
- });
+ const nodeResults: InfraNode[] = nodes.map(
+ (node: InfraBucket): InfraNode => {
+ return createNodeItem(options, node, node);
+ }
+ );
set(response, 'nodes', nodeResults);
return response;
} else {
diff --git a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts
index 05fbef753ec20..b32300f33672e 100644
--- a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts
+++ b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts
@@ -27,17 +27,19 @@ export class InfraFieldsDomain {
const fields: any = get(fieldCaps, 'fields');
const results: any = fields
- ? Object.keys(fields).map((name: keyof typeof fields): InfraField => {
- const fieldData: any = fields[name];
- const [type]: any = Object.keys(fieldData);
- const def: any = fieldData[type];
- return {
- aggregatable: def.aggregatable,
- name: String(name),
- searchable: def.searchable,
- type,
- };
- })
+ ? Object.keys(fields).map(
+ (name: keyof typeof fields): InfraField => {
+ const fieldData: any = fields[name];
+ const [type]: any = Object.keys(fieldData);
+ const def: any = fieldData[type];
+ return {
+ aggregatable: def.aggregatable,
+ name: String(name),
+ searchable: def.searchable,
+ type,
+ };
+ }
+ )
: [];
return sortBy(results, 'name');
}
From 3569ae5d665fd258525357fe4a858676dd2fbe4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Mon, 6 Aug 2018 23:51:02 +0200
Subject: [PATCH 3/6] Change log entries state to use the new graphql api
---
x-pack/package.json | 3 +
.../infra/common/graphql/introspection.json | 2216 +++++++++++++++++
.../graphql/shared/fragments.gql_query.ts | 16 +
.../graphql/shared}/index.ts | 5 +-
.../infra/common/graphql/shared/schema.gql.ts | 22 +
.../infra/common/graphql/typed_resolvers.ts | 82 +
x-pack/plugins/infra/common/graphql/types.ts | 98 +-
x-pack/plugins/infra/common/time/time_key.ts | 17 +-
.../components/logging/log_position_text.tsx | 6 +-
.../logging_legacy/state/entries/actions.ts | 20 +-
.../state/entries/api/extend_entries.ts | 74 -
.../state/entries/api/fetch_entries.ts | 67 -
.../state/entries/api/replace_entries.ts | 76 -
.../logging_legacy/state/entries/epics.ts | 299 +--
.../logging_legacy/state/entries/index.ts | 1 +
.../state/entries/load_more_operation.ts | 72 +
.../state/entries/load_operation.ts | 30 +
.../state/entries/log_entries.gql_query.ts | 50 +
.../logging_legacy/state/entries/reducer.ts | 220 +-
.../logging_legacy/state/entries/selectors.ts | 72 +-
.../logging_legacy/state/entries/state.ts | 32 +
.../containers/logging_legacy/state/epics.ts | 10 +-
.../state/search_results/epics.ts | 2 +-
.../logging_legacy/state/selectors.ts | 14 +-
.../logging_legacy/state/source/reducer.ts | 4 +-
.../logging_legacy/with_stream_items.ts | 43 +-
.../with_text_scale_controls_props.ts | 14 +-
.../with_text_wrap_controls_props.ts | 11 +-
.../with_time_controls_props.ts | 5 +-
.../public/lib/compose/kibana_compose.ts | 16 +-
x-pack/plugins/infra/public/lib/lib.d.ts | 4 +-
.../plugins/infra/public/pages/logs/logs.tsx | 67 +-
.../plugins/infra/public/pages/logs/store.ts | 23 +-
.../infra/public/utils/loading_state/index.ts | 18 +-
.../utils/loading_state/loading_progress.ts | 2 +-
.../utils/loading_state/loading_result.ts | 34 +-
.../infra/public/utils/log_entry/index.ts | 7 +
.../infra/public/utils/log_entry/log_entry.ts | 27 +
.../infra/public/utils/memoize_last.ts | 48 +
.../remote_state/remote_graphql_state.ts | 206 ++
.../plugins/infra/public/utils/typed_react.ts | 123 +
.../plugins/infra/public/utils/typed_redux.ts | 8 +-
.../plugins/infra/scripts/combined_schema.ts | 3 +-
.../scripts/generate_types_from_graphql.js | 23 +-
.../infra/server/graphql/fields/schema.gql.ts | 2 +-
x-pack/plugins/infra/server/graphql/index.ts | 10 +-
.../server/graphql/log_entries/resolvers.ts | 21 +-
.../server/graphql/log_entries/schema.gql.ts | 17 +-
.../lib/adapters/framework/adapter_types.ts | 81 +-
.../log_entries_domain/log_entries_domain.ts | 18 +-
.../plugins/infra/types/redux_observable.d.ts | 16 +-
x-pack/yarn.lock | 29 +-
yarn.lock | 4 +
53 files changed, 3473 insertions(+), 915 deletions(-)
create mode 100644 x-pack/plugins/infra/common/graphql/introspection.json
create mode 100644 x-pack/plugins/infra/common/graphql/shared/fragments.gql_query.ts
rename x-pack/plugins/infra/{public/graphql => common/graphql/shared}/index.ts (69%)
create mode 100644 x-pack/plugins/infra/common/graphql/shared/schema.gql.ts
create mode 100644 x-pack/plugins/infra/common/graphql/typed_resolvers.ts
delete mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/extend_entries.ts
delete mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/fetch_entries.ts
delete mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/replace_entries.ts
create mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_more_operation.ts
create mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_operation.ts
create mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/log_entries.gql_query.ts
create mode 100644 x-pack/plugins/infra/public/containers/logging_legacy/state/entries/state.ts
create mode 100644 x-pack/plugins/infra/public/utils/log_entry/index.ts
create mode 100644 x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
create mode 100644 x-pack/plugins/infra/public/utils/memoize_last.ts
create mode 100644 x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
create mode 100644 x-pack/plugins/infra/public/utils/typed_react.ts
diff --git a/x-pack/package.json b/x-pack/package.json
index 20fb35e9a2750..3e4240e99ca23 100644
--- a/x-pack/package.json
+++ b/x-pack/package.json
@@ -48,6 +48,7 @@
"@types/react-dom": "^16.0.5",
"@types/react-redux": "^6.0.2",
"@types/react-router-dom": "^4.2.6",
+ "@types/reduce-reducers": "^0.1.3",
"@types/sinon": "^5.0.0",
"@types/uuid": "^3.4.3",
"abab": "^1.0.4",
@@ -66,6 +67,7 @@
"enzyme-to-json": "3.3.1",
"expect.js": "0.3.1",
"graphql-code-generator": "^0.10.1",
+ "graphql-codegen-introspection-template": "^0.10.5",
"graphql-codegen-typescript-template": "^0.10.1",
"gulp": "3.9.1",
"gulp-load-plugins": "1.2.0",
@@ -184,6 +186,7 @@
"react-sticky": "^6.0.1",
"react-syntax-highlighter": "^5.7.0",
"react-vis": "^1.8.1",
+ "reduce-reducers": "^0.4.3",
"redux": "4.0.0",
"redux-actions": "2.2.1",
"redux-observable": "^1.0.0",
diff --git a/x-pack/plugins/infra/common/graphql/introspection.json b/x-pack/plugins/infra/common/graphql/introspection.json
new file mode 100644
index 0000000000000..742ec7dd4f5d5
--- /dev/null
+++ b/x-pack/plugins/infra/common/graphql/introspection.json
@@ -0,0 +1,2216 @@
+{
+ "__schema": {
+ "queryType": { "name": "Query" },
+ "mutationType": null,
+ "subscriptionType": null,
+ "types": [
+ {
+ "kind": "OBJECT",
+ "name": "Query",
+ "description": "",
+ "fields": [
+ {
+ "name": "fields",
+ "description": "",
+ "args": [
+ {
+ "name": "indexPattern",
+ "description": "",
+ "type": {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraIndexPatternInput",
+ "ofType": null
+ },
+ "defaultValue": "{pattern: \"metricbeat_read_only\", timeFieldName: \"@timestamp\"}"
+ }
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraField", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "source",
+ "description": "Get an infrastructure data source by id",
+ "args": [
+ {
+ "name": "id",
+ "description": "The id of the source",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "ID", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraSource", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "allSources",
+ "description": "Get a list of all infrastructure data sources",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraSource", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraIndexPatternInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "pattern",
+ "description": "The index pattern to use, defaults to '*'",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "timeFieldName",
+ "description": "The timefield to use, defaults to @timestamp",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "SCALAR",
+ "name": "String",
+ "description":
+ "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraField",
+ "description": "",
+ "fields": [
+ {
+ "name": "name",
+ "description": "",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "type",
+ "description": "",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "searchable",
+ "description": "",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "Boolean", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "aggregatable",
+ "description": "",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "Boolean", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "description": "The `Boolean` scalar type represents `true` or `false`.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "SCALAR",
+ "name": "ID",
+ "description":
+ "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraSource",
+ "description": "A source of infrastructure data",
+ "fields": [
+ {
+ "name": "id",
+ "description": "The id of the source",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "ID", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "configuration",
+ "description": "The raw configuration of the source",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraSourceConfiguration", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "status",
+ "description": "The status of the source",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraSourceStatus", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "logEntriesAround",
+ "description": "A consecutive span of log entries surrounding a point in time",
+ "args": [
+ {
+ "name": "key",
+ "description": "The sort key that corresponds to the point in time",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraTimeKeyInput", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "countBefore",
+ "description": "The maximum number of preceding to return",
+ "type": { "kind": "SCALAR", "name": "Int", "ofType": null },
+ "defaultValue": "0"
+ },
+ {
+ "name": "countAfter",
+ "description": "The maximum number of following to return",
+ "type": { "kind": "SCALAR", "name": "Int", "ofType": null },
+ "defaultValue": "0"
+ },
+ {
+ "name": "filterQuery",
+ "description": "The query to filter the log entries by",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "highlightQuery",
+ "description": "The query to highlight the log entries with",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraLogEntryInterval", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "logEntriesBetween",
+ "description": "A consecutive span of log entries within an interval",
+ "args": [
+ {
+ "name": "startKey",
+ "description": "The sort key that corresponds to the start of the interval",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraTimeKeyInput", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "endKey",
+ "description": "The sort key that corresponds to the end of the interval",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraTimeKeyInput", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "filterQuery",
+ "description": "The query to filter the log entries by",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "highlightQuery",
+ "description": "The query to highlight the log entries with",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraLogEntryInterval", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "map",
+ "description": "A hierarchy of hosts, pods, containers, services or arbitrary groups",
+ "args": [
+ {
+ "name": "timerange",
+ "description": "",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraTimerangeInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "filters",
+ "description": "",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraFilterInput", "ofType": null }
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": { "kind": "OBJECT", "name": "InfraResponse", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraSourceConfiguration",
+ "description": "A set of configuration options for an infrastructure data source",
+ "fields": [
+ {
+ "name": "metricAlias",
+ "description": "The alias to read metric data from",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "logAlias",
+ "description": "The alias to read log data from",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "fields",
+ "description": "The field mapping to use for this source",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraSourceFields", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraSourceFields",
+ "description": "A mapping of semantic fields to their document counterparts",
+ "fields": [
+ {
+ "name": "container",
+ "description": "The field to identify a container by",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "hostname",
+ "description": "The fields to identify a host by",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "message",
+ "description":
+ "The fields that may contain the log event message. The first field found win.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pod",
+ "description": "The field to identify a pod by",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "tiebreaker",
+ "description":
+ "The field to use as a tiebreaker for log events that have identical timestamps",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "timestamp",
+ "description": "The field to use as a timestamp for metrics and logs",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraSourceStatus",
+ "description": "The status of an infrastructure data source",
+ "fields": [
+ {
+ "name": "metricAliasExists",
+ "description": "Whether the configured metric alias exists",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "logAliasExists",
+ "description": "Whether the configured log alias exists",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "metricIndices",
+ "description": "The list of indices in the metric alias",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "logIndices",
+ "description": "The list of indices in the log alias",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraTimeKeyInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "time",
+ "description": "",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "tiebreaker",
+ "description": "",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "SCALAR",
+ "name": "Float",
+ "description":
+ "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "SCALAR",
+ "name": "Int",
+ "description":
+ "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraLogEntryInterval",
+ "description": "A consecutive sequence of log entries",
+ "fields": [
+ {
+ "name": "start",
+ "description":
+ "The key corresponding to the start of the interval covered by the entries",
+ "args": [],
+ "type": { "kind": "OBJECT", "name": "InfraTimeKey", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "end",
+ "description":
+ "The key corresponding to the end of the interval covered by the entries",
+ "args": [],
+ "type": { "kind": "OBJECT", "name": "InfraTimeKey", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "hasMoreBefore",
+ "description": "Whether there are more log entries available before the start",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "hasMoreAfter",
+ "description": "Whether there are more log entries available after the end",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "filterQuery",
+ "description": "The query the log entries were filtered by",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "highlightQuery",
+ "description": "The query the log entries were highlighted with",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "entries",
+ "description": "A list of the log entries",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraLogEntry", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraTimeKey",
+ "description": "A representation of the log entry's position in the event stream",
+ "fields": [
+ {
+ "name": "time",
+ "description": "The timestamp of the event that the log entry corresponds to",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "tiebreaker",
+ "description": "The tiebreaker that disambiguates events with the same timestamp",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraLogEntry",
+ "description": "A log entry",
+ "fields": [
+ {
+ "name": "key",
+ "description":
+ "A unique representation of the log entry's position in the event stream",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraTimeKey", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "gid",
+ "description": "The log entry's id",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "source",
+ "description": "The source id",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "message",
+ "description": "A list of the formatted log entry segments",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "UNION", "name": "InfraLogMessageSegment", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "UNION",
+ "name": "InfraLogMessageSegment",
+ "description": "A segment of the log entry message",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": [
+ { "kind": "OBJECT", "name": "InfraLogMessageFieldSegment", "ofType": null },
+ { "kind": "OBJECT", "name": "InfraLogMessageConstantSegment", "ofType": null }
+ ]
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraLogMessageFieldSegment",
+ "description": "A segment of the log entry message that was derived from a field",
+ "fields": [
+ {
+ "name": "field",
+ "description": "The field the segment was derived from",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "value",
+ "description": "The segment's message",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "highlights",
+ "description": "A list of highlighted substrings of the value",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraLogMessageConstantSegment",
+ "description": "A segment of the log entry message that was derived from a field",
+ "fields": [
+ {
+ "name": "constant",
+ "description": "The segment's message",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraTimerangeInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "interval",
+ "description":
+ "The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "to",
+ "description": "The end of the timerange",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "from",
+ "description": "The beginning of the timerange",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraFilterInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "type",
+ "description": "The type of filter to use",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "InfraFilterType", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "value",
+ "description": "The filter value",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "field",
+ "description": "The field name for a match query",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "InfraFilterType",
+ "description": "",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "query_string",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ { "name": "match", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "exists", "description": "", "isDeprecated": false, "deprecationReason": null }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraResponse",
+ "description": "",
+ "fields": [
+ {
+ "name": "nodes",
+ "description": "",
+ "args": [
+ {
+ "name": "path",
+ "description": "",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraPathInput", "ofType": null }
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraNode", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraPathInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "type",
+ "description": "The type of path",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "InfraPathType", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "label",
+ "description":
+ "The label to use in the results for the group by for the terms group by",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "field",
+ "description":
+ "The field to group by from a terms aggregation, this is ignored by the filter type",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "filters",
+ "description": "The fitlers for the filter group by",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraPathFilterInput", "ofType": null }
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "InfraPathType",
+ "description": "",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ { "name": "terms", "description": "", "isDeprecated": false, "deprecationReason": null },
+ {
+ "name": "filters",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ { "name": "hosts", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "pods", "description": "", "isDeprecated": false, "deprecationReason": null },
+ {
+ "name": "containers",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraPathFilterInput",
+ "description": "A group by filter",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "label",
+ "description":
+ "The label for the filter, this will be used as the group name in the final results",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "query",
+ "description": "The query string query",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraNode",
+ "description": "",
+ "fields": [
+ {
+ "name": "path",
+ "description": "",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraNodePath", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "metrics",
+ "description": "",
+ "args": [
+ {
+ "name": "metrics",
+ "description": "",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraMetricInput", "ofType": null }
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "InfraNodeMetric", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraNodePath",
+ "description": "",
+ "fields": [
+ {
+ "name": "value",
+ "description": "",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraMetricInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "type",
+ "description": "The type of metric",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "InfraMetricType", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "aggs",
+ "description": "The aggregations for custom metrics",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "INPUT_OBJECT", "name": "InfraMetricAggInput", "ofType": null }
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "InfraMetricType",
+ "description": "",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ { "name": "count", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "cpu", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "memory", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "tx", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "rx", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "disk", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "custom", "description": "", "isDeprecated": false, "deprecationReason": null }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "InfraMetricAggInput",
+ "description": "",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "id",
+ "description":
+ "The UUID of the metric, this is used by pipeline aggregations to back reference an InfraMetricAggInput",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "ID", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "type",
+ "description": "The type of aggregation",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "InfraMetricAggregationType", "ofType": null }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "field",
+ "description":
+ "The field to use for the aggregation, this is only used for metric aggregations",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "metric",
+ "description":
+ "The metric to referece for the aggregation, this is only used for pipeline aggreations",
+ "type": { "kind": "SCALAR", "name": "ID", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "settings",
+ "description":
+ "Additional settings for pipeline aggregations in a key:value comma delimited format",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ },
+ {
+ "name": "script",
+ "description": "Script field for bucket_script aggregations",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "InfraMetricAggregationType",
+ "description": "",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ { "name": "avg", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "min", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "max", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "sum", "description": "", "isDeprecated": false, "deprecationReason": null },
+ {
+ "name": "bucket_script",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "derivative",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "moving_average",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "positive_only",
+ "description": "",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "InfraNodeMetric",
+ "description": "",
+ "fields": [
+ {
+ "name": "name",
+ "description": "",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "value",
+ "description": "",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__Schema",
+ "description":
+ "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.",
+ "fields": [
+ {
+ "name": "types",
+ "description": "A list of all types supported by this server.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "queryType",
+ "description": "The type that query operations will be rooted at.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "mutationType",
+ "description":
+ "If this server supports mutation, the type that mutation operations will be rooted at.",
+ "args": [],
+ "type": { "kind": "OBJECT", "name": "__Type", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "subscriptionType",
+ "description":
+ "If this server support subscription, the type that subscription operations will be rooted at.",
+ "args": [],
+ "type": { "kind": "OBJECT", "name": "__Type", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "directives",
+ "description": "A list of all directives supported by this server.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Directive", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__Type",
+ "description":
+ "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.",
+ "fields": [
+ {
+ "name": "kind",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "__TypeKind", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "description",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "fields",
+ "description": null,
+ "args": [
+ {
+ "name": "includeDeprecated",
+ "description": null,
+ "type": { "kind": "SCALAR", "name": "Boolean", "ofType": null },
+ "defaultValue": "false"
+ }
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Field", "ofType": null }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "interfaces",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "possibleTypes",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "enumValues",
+ "description": null,
+ "args": [
+ {
+ "name": "includeDeprecated",
+ "description": null,
+ "type": { "kind": "SCALAR", "name": "Boolean", "ofType": null },
+ "defaultValue": "false"
+ }
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__EnumValue", "ofType": null }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "inputFields",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__InputValue", "ofType": null }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ofType",
+ "description": null,
+ "args": [],
+ "type": { "kind": "OBJECT", "name": "__Type", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "__TypeKind",
+ "description": "An enum describing what kind of type a given `__Type` is.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "SCALAR",
+ "description": "Indicates this type is a scalar.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "OBJECT",
+ "description":
+ "Indicates this type is an object. `fields` and `interfaces` are valid fields.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INTERFACE",
+ "description":
+ "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "UNION",
+ "description": "Indicates this type is a union. `possibleTypes` is a valid field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ENUM",
+ "description": "Indicates this type is an enum. `enumValues` is a valid field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INPUT_OBJECT",
+ "description":
+ "Indicates this type is an input object. `inputFields` is a valid field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "LIST",
+ "description": "Indicates this type is a list. `ofType` is a valid field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "NON_NULL",
+ "description": "Indicates this type is a non-null. `ofType` is a valid field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__Field",
+ "description":
+ "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.",
+ "fields": [
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "description",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "args",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__InputValue", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "type",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "isDeprecated",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "deprecationReason",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__InputValue",
+ "description":
+ "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.",
+ "fields": [
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "description",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "type",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__Type", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "defaultValue",
+ "description":
+ "A GraphQL-formatted string representing the default value for this input value.",
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__EnumValue",
+ "description":
+ "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.",
+ "fields": [
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "description",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "isDeprecated",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "deprecationReason",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "__Directive",
+ "description":
+ "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.",
+ "fields": [
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "description",
+ "description": null,
+ "args": [],
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "locations",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "ENUM", "name": "__DirectiveLocation", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "args",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "OBJECT", "name": "__InputValue", "ofType": null }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "onOperation",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": true,
+ "deprecationReason": "Use `locations`."
+ },
+ {
+ "name": "onFragment",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": true,
+ "deprecationReason": "Use `locations`."
+ },
+ {
+ "name": "onField",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "isDeprecated": true,
+ "deprecationReason": "Use `locations`."
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "__DirectiveLocation",
+ "description":
+ "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "QUERY",
+ "description": "Location adjacent to a query operation.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "MUTATION",
+ "description": "Location adjacent to a mutation operation.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "SUBSCRIPTION",
+ "description": "Location adjacent to a subscription operation.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FIELD",
+ "description": "Location adjacent to a field.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FRAGMENT_DEFINITION",
+ "description": "Location adjacent to a fragment definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FRAGMENT_SPREAD",
+ "description": "Location adjacent to a fragment spread.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INLINE_FRAGMENT",
+ "description": "Location adjacent to an inline fragment.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "SCHEMA",
+ "description": "Location adjacent to a schema definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "SCALAR",
+ "description": "Location adjacent to a scalar definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "OBJECT",
+ "description": "Location adjacent to an object type definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "FIELD_DEFINITION",
+ "description": "Location adjacent to a field definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ARGUMENT_DEFINITION",
+ "description": "Location adjacent to an argument definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INTERFACE",
+ "description": "Location adjacent to an interface definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "UNION",
+ "description": "Location adjacent to a union definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ENUM",
+ "description": "Location adjacent to an enum definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "ENUM_VALUE",
+ "description": "Location adjacent to an enum value definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INPUT_OBJECT",
+ "description": "Location adjacent to an input object type definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "INPUT_FIELD_DEFINITION",
+ "description": "Location adjacent to an input object field definition.",
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
+ {
+ "kind": "ENUM",
+ "name": "InfraOperator",
+ "description": "",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ { "name": "gt", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "gte", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "lt", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "lte", "description": "", "isDeprecated": false, "deprecationReason": null },
+ { "name": "eq", "description": "", "isDeprecated": false, "deprecationReason": null }
+ ],
+ "possibleTypes": null
+ }
+ ],
+ "directives": [
+ {
+ "name": "skip",
+ "description":
+ "Directs the executor to skip this field or fragment when the `if` argument is true.",
+ "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"],
+ "args": [
+ {
+ "name": "if",
+ "description": "Skipped when true.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ]
+ },
+ {
+ "name": "include",
+ "description":
+ "Directs the executor to include this field or fragment only when the `if` argument is true.",
+ "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"],
+ "args": [
+ {
+ "name": "if",
+ "description": "Included when true.",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": { "kind": "SCALAR", "name": "Boolean", "ofType": null }
+ },
+ "defaultValue": null
+ }
+ ]
+ },
+ {
+ "name": "deprecated",
+ "description": "Marks an element of a GraphQL schema as no longer supported.",
+ "locations": ["FIELD_DEFINITION", "ENUM_VALUE"],
+ "args": [
+ {
+ "name": "reason",
+ "description":
+ "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).",
+ "type": { "kind": "SCALAR", "name": "String", "ofType": null },
+ "defaultValue": "\"No longer supported\""
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/x-pack/plugins/infra/common/graphql/shared/fragments.gql_query.ts b/x-pack/plugins/infra/common/graphql/shared/fragments.gql_query.ts
new file mode 100644
index 0000000000000..44a5be6a85638
--- /dev/null
+++ b/x-pack/plugins/infra/common/graphql/shared/fragments.gql_query.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import gql from 'graphql-tag';
+
+export const sharedFragments = {
+ InfraTimeKey: gql`
+ fragment InfraTimeKeyFields on InfraTimeKey {
+ time
+ tiebreaker
+ }
+ `,
+};
diff --git a/x-pack/plugins/infra/public/graphql/index.ts b/x-pack/plugins/infra/common/graphql/shared/index.ts
similarity index 69%
rename from x-pack/plugins/infra/public/graphql/index.ts
rename to x-pack/plugins/infra/common/graphql/shared/index.ts
index 70a1ab63f0f55..56c8675e76caf 100644
--- a/x-pack/plugins/infra/public/graphql/index.ts
+++ b/x-pack/plugins/infra/common/graphql/shared/index.ts
@@ -4,6 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { rootSchema } from '../../common/graphql/root/schema.gql';
-
-export const schemas = [rootSchema];
+export { sharedFragments } from './fragments.gql_query';
+export { sharedSchema } from './schema.gql';
diff --git a/x-pack/plugins/infra/common/graphql/shared/schema.gql.ts b/x-pack/plugins/infra/common/graphql/shared/schema.gql.ts
new file mode 100644
index 0000000000000..4cbfa2f18d7ad
--- /dev/null
+++ b/x-pack/plugins/infra/common/graphql/shared/schema.gql.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import gql from 'graphql-tag';
+
+export const sharedSchema = gql`
+ "A representation of the log entry's position in the event stream"
+ type InfraTimeKey {
+ "The timestamp of the event that the log entry corresponds to"
+ time: Float!
+ "The tiebreaker that disambiguates events with the same timestamp"
+ tiebreaker: Float!
+ }
+
+ input InfraTimeKeyInput {
+ time: Float!
+ tiebreaker: Float!
+ }
+`;
diff --git a/x-pack/plugins/infra/common/graphql/typed_resolvers.ts b/x-pack/plugins/infra/common/graphql/typed_resolvers.ts
new file mode 100644
index 0000000000000..50b169601894b
--- /dev/null
+++ b/x-pack/plugins/infra/common/graphql/typed_resolvers.ts
@@ -0,0 +1,82 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { GraphQLResolveInfo } from 'graphql';
+
+type BasicResolver = (
+ parent: any,
+ args: Args,
+ context: any,
+ info: GraphQLResolveInfo
+) => Promise | Result;
+
+type InfraResolverResult =
+ | Promise
+ | Promise<{ [P in keyof R]: () => Promise }>
+ | { [P in keyof R]: () => Promise }
+ | { [P in keyof R]: () => R[P] }
+ | R;
+
+export type InfraResolvedResult = Resolver extends InfraResolver<
+ infer Result,
+ any,
+ any,
+ any
+>
+ ? Result
+ : never;
+
+export type SubsetResolverWithFields = R extends BasicResolver<
+ Array,
+ infer ArgsInArray
+>
+ ? BasicResolver<
+ Array>>,
+ ArgsInArray
+ >
+ : R extends BasicResolver
+ ? BasicResolver>, Args>
+ : never;
+
+export type SubsetResolverWithoutFields = R extends BasicResolver<
+ Array,
+ infer ArgsInArray
+>
+ ? BasicResolver<
+ Array>>,
+ ArgsInArray
+ >
+ : R extends BasicResolver
+ ? BasicResolver>, Args>
+ : never;
+
+export type InfraResolver = (
+ parent: Parent,
+ args: Args,
+ context: Context,
+ info: GraphQLResolveInfo
+) => InfraResolverResult;
+
+export type InfraResolverOf = Resolver extends BasicResolver<
+ infer Result,
+ infer Args
+>
+ ? InfraResolver
+ : never;
+
+export type InfraResolverWithFields<
+ Resolver,
+ Parent,
+ Context,
+ IncludedFields extends string
+> = InfraResolverOf, Parent, Context>;
+
+export type InfraResolverWithoutFields<
+ Resolver,
+ Parent,
+ Context,
+ ExcludedFields extends string
+> = InfraResolverOf, Parent, Context>;
diff --git a/x-pack/plugins/infra/common/graphql/types.ts b/x-pack/plugins/infra/common/graphql/types.ts
index 71050d5482bfe..5f32a8bfb0690 100644
--- a/x-pack/plugins/infra/common/graphql/types.ts
+++ b/x-pack/plugins/infra/common/graphql/types.ts
@@ -8,18 +8,18 @@ type Resolver = (
info: GraphQLResolveInfo
) => Promise | Result;
+export interface Query {
+ fields?: (InfraField | null)[] | null;
+ source: InfraSource /** Get an infrastructure data source by id */;
+ allSources: InfraSource[] /** Get a list of all infrastructure data sources */;
+}
+
export interface InfraField {
name?: string | null;
type?: string | null;
searchable?: boolean | null;
aggregatable?: boolean | null;
}
-
-export interface Query {
- fields?: (InfraField | null)[] | null;
- source: InfraSource /** Get an infrastructure data source by id */;
- allSources: InfraSource[] /** Get a list of all infrastructure data sources */;
-}
/** A source of infrastructure data */
export interface InfraSource {
id: string /** The id of the source */;
@@ -55,6 +55,8 @@ export interface InfraSourceStatus {
export interface InfraLogEntryInterval {
start?: InfraTimeKey | null /** The key corresponding to the start of the interval covered by the entries */;
end?: InfraTimeKey | null /** The key corresponding to the end of the interval covered by the entries */;
+ hasMoreBefore: boolean /** Whether there are more log entries available before the start */;
+ hasMoreAfter: boolean /** Whether there are more log entries available after the end */;
filterQuery?: string | null /** The query the log entries were filtered by */;
highlightQuery?: string | null /** The query the log entries were highlighted with */;
entries: InfraLogEntry[] /** A list of the log entries */;
@@ -119,6 +121,20 @@ export namespace QueryResolvers {
export type AllSourcesResolver = Resolver;
}
+
+export namespace InfraFieldResolvers {
+ export interface Resolvers {
+ name?: NameResolver;
+ type?: TypeResolver;
+ searchable?: SearchableResolver;
+ aggregatable?: AggregatableResolver;
+ }
+
+ export type NameResolver = Resolver;
+ export type TypeResolver = Resolver;
+ export type SearchableResolver = Resolver;
+ export type AggregatableResolver = Resolver;
+}
/** A source of infrastructure data */
export namespace InfraSourceResolvers {
export interface Resolvers {
@@ -205,6 +221,8 @@ export namespace InfraLogEntryIntervalResolvers {
export interface Resolvers {
start?: StartResolver /** The key corresponding to the start of the interval covered by the entries */;
end?: EndResolver /** The key corresponding to the end of the interval covered by the entries */;
+ hasMoreBefore?: HasMoreBeforeResolver /** Whether there are more log entries available before the start */;
+ hasMoreAfter?: HasMoreAfterResolver /** Whether there are more log entries available after the end */;
filterQuery?: FilterQueryResolver /** The query the log entries were filtered by */;
highlightQuery?: HighlightQueryResolver /** The query the log entries were highlighted with */;
entries?: EntriesResolver /** A list of the log entries */;
@@ -212,6 +230,8 @@ export namespace InfraLogEntryIntervalResolvers {
export type StartResolver = Resolver;
export type EndResolver = Resolver;
+ export type HasMoreBeforeResolver = Resolver;
+ export type HasMoreAfterResolver = Resolver;
export type FilterQueryResolver = Resolver;
export type HighlightQueryResolver = Resolver;
export type EntriesResolver = Resolver;
@@ -435,13 +455,12 @@ export enum InfraOperator {
/** A segment of the log entry message */
export type InfraLogMessageSegment = InfraLogMessageFieldSegment | InfraLogMessageConstantSegment;
-export namespace MapQuery {
+export namespace LogEntries {
export type Variables = {
- id: string;
- timerange: InfraTimerangeInput;
- filters?: InfraFilterInput[] | null;
- metrics?: InfraMetricInput[] | null;
- path?: InfraPathInput[] | null;
+ sourceId?: string | null;
+ timeKey: InfraTimeKeyInput;
+ countBefore?: number | null;
+ countAfter?: number | null;
};
export type Query = {
@@ -452,28 +471,55 @@ export namespace MapQuery {
export type Source = {
__typename?: 'InfraSource';
id: string;
- map?: Map | null;
+ logEntriesAround: LogEntriesAround;
};
- export type Map = {
- __typename?: 'InfraResponse';
- nodes: Nodes[];
+ export type LogEntriesAround = {
+ __typename?: 'InfraLogEntryInterval';
+ start?: Start | null;
+ end?: End | null;
+ hasMoreBefore: boolean;
+ hasMoreAfter: boolean;
+ entries: Entries[];
};
- export type Nodes = {
- __typename?: 'InfraNode';
- path: Path[];
- metrics: Metrics[];
+ export type Start = InfraTimeKeyFields.Fragment;
+
+ export type End = InfraTimeKeyFields.Fragment;
+
+ export type Entries = {
+ __typename?: 'InfraLogEntry';
+ gid: string;
+ key: Key;
+ message: Message[];
+ };
+
+ export type Key = {
+ __typename?: 'InfraTimeKey';
+ time: number;
+ tiebreaker: number;
};
- export type Path = {
- __typename?: 'InfraNodePath';
+ export type Message =
+ | InfraLogMessageFieldSegmentInlineFragment
+ | InfraLogMessageConstantSegmentInlineFragment;
+
+ export type InfraLogMessageFieldSegmentInlineFragment = {
+ __typename?: 'InfraLogMessageFieldSegment';
+ field: string;
value: string;
};
- export type Metrics = {
- __typename?: 'InfraNodeMetric';
- name: string;
- value: number;
+ export type InfraLogMessageConstantSegmentInlineFragment = {
+ __typename?: 'InfraLogMessageConstantSegment';
+ constant: string;
+ };
+}
+
+export namespace InfraTimeKeyFields {
+ export type Fragment = {
+ __typename?: 'InfraTimeKey';
+ time: number;
+ tiebreaker: number;
};
}
diff --git a/x-pack/plugins/infra/common/time/time_key.ts b/x-pack/plugins/infra/common/time/time_key.ts
index 1693e8775ccad..966c4ac3c6e08 100644
--- a/x-pack/plugins/infra/common/time/time_key.ts
+++ b/x-pack/plugins/infra/common/time/time_key.ts
@@ -5,6 +5,7 @@
*/
import { ascending, bisector } from 'd3-array';
+import pick from 'lodash/fp/pick';
export interface TimeKey {
time: number;
@@ -20,6 +21,9 @@ export const isTimeKey = (value: any): value is TimeKey =>
typeof value.time === 'number' &&
typeof value.tiebreaker === 'number';
+export const pickTimeKey = (value: T): TimeKey =>
+ pick(['time', 'tiebreaker'], value);
+
export function compareTimeKeys(
firstKey: TimeKey,
secondKey: TimeKey,
@@ -49,24 +53,27 @@ export const compareToTimeKey = (
compareValues?: Comparator
) => (value: Value, key: TimeKey) => compareTimeKeys(keyAccessor(value), key, compareValues);
-export const getAtTimeKey = (
+export const getIndexAtTimeKey = (
keyAccessor: (value: Value) => TimeKey,
compareValues?: Comparator
) => {
const compator = compareToTimeKey(keyAccessor, compareValues);
const collectionBisector = bisector(compator);
- return (collection: Value[], key: TimeKey): Value | undefined => {
+ return (collection: Value[], key: TimeKey): number | null => {
const index = collectionBisector.left(collection, key);
if (index >= collection.length) {
- return;
+ return null;
}
if (compator(collection[index], key) !== 0) {
- return;
+ return null;
}
- return collection[index];
+ return index;
};
};
+
+export const timeKeyIsBetween = (min: TimeKey, max: TimeKey, operand: TimeKey) =>
+ compareTimeKeys(min, operand) <= 0 && compareTimeKeys(max, operand) >= 0;
diff --git a/x-pack/plugins/infra/public/components/logging/log_position_text.tsx b/x-pack/plugins/infra/public/components/logging/log_position_text.tsx
index f8f165220e5c1..c78a6ee82abcc 100644
--- a/x-pack/plugins/infra/public/components/logging/log_position_text.tsx
+++ b/x-pack/plugins/infra/public/components/logging/log_position_text.tsx
@@ -8,8 +8,8 @@ import { EuiIcon } from '@elastic/eui';
import classNames from 'classnames';
import * as React from 'react';
-import { LogEntry } from '../../../common/log_entry';
import { formatTime } from '../../../common/time';
+import { LogEntry } from '../../utils/log_entry';
interface LogPositionTextProps {
className?: string;
@@ -27,11 +27,11 @@ export class LogPositionText extends React.PureComponent
Showing
- {firstVisibleLogEntry ? formatTime(firstVisibleLogEntry.fields.time) : 'unknown'}
+ {firstVisibleLogEntry ? formatTime(firstVisibleLogEntry.key.time) : 'unknown'}
{' '}
{' '}
- {lastVisibleLogEntry ? formatTime(lastVisibleLogEntry.fields.time) : 'unknown'}
+ {lastVisibleLogEntry ? formatTime(lastVisibleLogEntry.key.time) : 'unknown'}
);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/actions.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/actions.ts
index 1887df6a5c93e..0301b421edd53 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/actions.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/actions.ts
@@ -6,12 +6,18 @@
import actionCreatorFactory from 'typescript-fsa';
-import { LogEntry, LogEntryTime } from '../../../../../common/log_entry';
+import { TimeKey } from '../../../../../common/time';
+import { LogEntry } from '../../../../utils/log_entry';
+import { loadMoreEntriesActionCreators } from './load_more_operation';
+import { loadEntriesActionCreators } from './load_operation';
const actionCreator = actionCreatorFactory('kibana/logging/entries');
+export const loadEntries = loadEntriesActionCreators.resolve;
+export const loadMoreEntries = loadMoreEntriesActionCreators.resolve;
+
/**
- * REPLACE_ENTRIES
+ * REPLACE_ENTRIES (deprecated)
*/
export interface ReplaceEntriesPayload {
@@ -34,7 +40,7 @@ export const replaceEntries = actionCreator.async('CONSOLIDATE_ENTRIES');
@@ -68,9 +74,9 @@ export const consolidateEntries = actionCreator('CONS
export interface ReportVisibleEntriesPayload {
pagesAfterEnd: number;
pagesBeforeStart: number;
- endKey: LogEntryTime | null;
- middleKey: LogEntryTime | null;
- startKey: LogEntryTime | null;
+ endKey: TimeKey | null;
+ middleKey: TimeKey | null;
+ startKey: TimeKey | null;
}
export const reportVisibleEntries = actionCreator(
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/extend_entries.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/extend_entries.ts
deleted file mode 100644
index d70755191d336..0000000000000
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/extend_entries.ts
+++ /dev/null
@@ -1,74 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { Action } from 'redux';
-import { Observable } from 'rxjs';
-import { catchError, map, startWith } from 'rxjs/operators';
-
-import { LogEntryFieldsMapping, LogEntryTime } from '../../../../../../common/log_entry';
-import { InfraObservableApi } from '../../../../../lib/lib';
-import { extendEntriesEnd, extendEntriesStart } from '../actions';
-import { fetchAdjacentEntries } from './fetch_entries';
-
-export const extendEntriesStart$ = (
- postToApi: InfraObservableApi['post'],
- target: LogEntryTime,
- count: number,
- indices: string[],
- fields: LogEntryFieldsMapping
-): Observable => {
- const params = {
- count,
- target,
- };
- return fetchAdjacentEntries(postToApi, 0, count, fields, indices, target).pipe(
- map(({ before }) =>
- extendEntriesStart.done({
- params,
- result: {
- logEntries: before,
- },
- })
- ),
- catchError(error => [
- extendEntriesStart.failed({
- error,
- params,
- }),
- ]),
- startWith(extendEntriesStart.started(params))
- );
-};
-
-export const extendEntriesEnd$ = (
- postToApi: InfraObservableApi['post'],
- target: LogEntryTime,
- count: number,
- indices: string[],
- fields: LogEntryFieldsMapping
-): Observable => {
- const params = {
- count,
- target,
- };
- return fetchAdjacentEntries(postToApi, count, 0, fields, indices, target).pipe(
- map(({ after }) =>
- extendEntriesEnd.done({
- params,
- result: {
- logEntries: after.slice(1),
- },
- })
- ),
- catchError(error => [
- extendEntriesEnd.failed({
- error,
- params,
- }),
- ]),
- startWith(extendEntriesEnd.started(params))
- );
-};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/fetch_entries.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/fetch_entries.ts
deleted file mode 100644
index 9820760af099e..0000000000000
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/fetch_entries.ts
+++ /dev/null
@@ -1,67 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { Observable } from 'rxjs';
-import { map } from 'rxjs/operators';
-
-import {
- AdjacentLogEntriesApiPostPayload,
- AdjacentLogEntriesApiPostResponse,
- LatestLogEntriesApiPostPayload,
- LatestLogEntriesApiPostResponse,
-} from '../../../../../../common/http_api';
-import { LogEntry, LogEntryFieldsMapping, LogEntryTime } from '../../../../../../common/log_entry';
-import { InfraObservableApi } from '../../../../../lib/lib';
-
-export interface CommonFetchEntriesDependencies {
- postToApi$: Observable;
- selectSourceCoreFields: (state: State) => LogEntryFieldsMapping;
- selectSourceIndices: (state: State) => string[];
-}
-
-export type FetchAdjacentEntriesResult = Observable<{
- after: LogEntry[];
- before: LogEntry[];
-}>;
-
-export const fetchAdjacentEntries = (
- postToApi: InfraObservableApi['post'],
- after: number,
- before: number,
- fields: LogEntryFieldsMapping,
- indices: string[],
- target: LogEntryTime
-): FetchAdjacentEntriesResult =>
- postToApi({
- body: {
- after,
- before,
- fields,
- indices,
- target: {
- tiebreaker: target.tiebreaker,
- time: target.time,
- },
- },
- url: `logging/adjacent-entries`,
- }).pipe(map(({ response }) => response.entries));
-
-export type FetchLatestEntriesResult = Observable;
-
-export const fetchLatestEntries = (
- postToApi: InfraObservableApi['post'],
- count: number,
- indices: string[],
- fields: LogEntryFieldsMapping
-): FetchLatestEntriesResult =>
- postToApi({
- body: {
- count,
- fields,
- indices,
- },
- url: `logging/latest-entries`,
- }).pipe(map(({ response }) => response.entries));
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/replace_entries.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/replace_entries.ts
deleted file mode 100644
index 221578b4d7c4f..0000000000000
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/api/replace_entries.ts
+++ /dev/null
@@ -1,76 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { Action } from 'redux';
-import { Observable } from 'rxjs';
-import { catchError, map, startWith } from 'rxjs/operators';
-
-import { LogEntryFieldsMapping, LogEntryTime } from '../../../../../../common/log_entry';
-import { InfraObservableApi } from '../../../../../lib/lib';
-import { replaceEntries } from '../actions';
-import { fetchAdjacentEntries, fetchLatestEntries } from './fetch_entries';
-
-export const replaceEntries$ = (
- postToApi: InfraObservableApi['post'],
- target: LogEntryTime,
- count: number,
- indices: string[],
- fields: LogEntryFieldsMapping
-): Observable => {
- const params = {
- clearEagerly: true,
- count,
- };
- return fetchAdjacentEntries(postToApi, count, count, fields, indices, target).pipe(
- map(({ before, after }) =>
- replaceEntries.done({
- params,
- result: {
- logEntriesAfter: after,
- logEntriesBefore: before,
- },
- })
- ),
- catchError(error => [
- replaceEntries.failed({
- error,
- params,
- }),
- ]),
- startWith(replaceEntries.started(params))
- );
-};
-
-export const replaceEntriesWithLatest$ = (
- postToApi: InfraObservableApi['post'],
- count: number,
- indices: string[],
- fields: LogEntryFieldsMapping,
- clearEagerly: boolean
-): Observable => {
- const params = {
- clearEagerly,
- count,
- };
- return fetchLatestEntries(postToApi, count, indices, fields).pipe(
- map(entries =>
- replaceEntries.done({
- params,
- result: {
- logEntriesAfter: [],
- logEntriesBefore: entries,
- },
- })
- ),
- catchError(error => [
- replaceEntries.failed({
- error,
- params,
- }),
- ]),
- startWith(replaceEntries.started(params))
- );
-};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
index 34f7bc140cfd3..691f140546add 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
@@ -4,248 +4,125 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import pick from 'lodash/fp/pick';
import { Action } from 'redux';
-import { Epic } from 'redux-observable';
-import { interval, merge } from 'rxjs';
-import {
- debounceTime,
- exhaustMap,
- filter,
- map,
- startWith,
- switchMap,
- takeUntil,
- withLatestFrom,
-} from 'rxjs/operators';
+import { combineEpics, Epic, EpicWithState } from 'redux-observable';
+import { /*interval,*/ merge, Observable } from 'rxjs';
+import { exhaustMap, filter, map, withLatestFrom } from 'rxjs/operators';
-import { getLogEntryKey, isBetween, LogEntry } from '../../../../../common/log_entry';
-import {
- isExhaustedLoadingResult,
- isFailureLoadingResult,
- isIntervalLoadingPolicy,
- isRunningLoadingProgress,
- LoadingState,
-} from '../../../../utils/loading_state';
+import { pickTimeKey, TimeKey, timeKeyIsBetween } from '../../../../../common/time';
+import { InfraApolloClient } from '../../../../lib/lib';
import { targetActions } from '../target';
import {
- consolidateEntries,
+ loadEntries,
+ loadMoreEntries,
reportVisibleEntries,
- startLiveStreaming,
- stopLiveStreaming,
+ // startLiveStreaming,
+ // stopLiveStreaming,
} from './actions';
-import { extendEntriesEnd$, extendEntriesStart$ } from './api/extend_entries';
-import { CommonFetchEntriesDependencies } from './api/fetch_entries';
-import { replaceEntries$, replaceEntriesWithLatest$ } from './api/replace_entries';
+import { loadMoreEntriesEpic } from './load_more_operation';
+import { loadEntriesEpic } from './load_operation';
-const ASSUMED_ENTRIES_PER_PAGE = 100;
+const LOAD_CHUNK_SIZE = 200;
const DESIRED_BUFFER_PAGES = 2;
-const DEFAULT_INTERVAL_ENTRIES = (2 * DESIRED_BUFFER_PAGES + 1) * ASSUMED_ENTRIES_PER_PAGE;
-const MIN_CHUNK_SIZE = 25;
-const VISIBLE_INTERVAL_SETTLE_TIMEOUT = 2000;
-interface ManageStreamIntervalDependencies extends CommonFetchEntriesDependencies {
- selectFirstEntry: (state: State) => LogEntry | null;
- selectLastEntry: (state: State) => LogEntry | null;
- selectEntriesStartLoadingState: (state: State) => LoadingState;
- selectEntriesEndLoadingState: (state: State) => LoadingState;
+interface ManageEntriesDependencies {
+ selectEntriesStart: (state: State) => TimeKey | null;
+ selectEntriesEnd: (state: State) => TimeKey | null;
+ selectHasMoreBeforeStart: (state: State) => boolean;
+ selectHasMoreAfterEnd: (state: State) => boolean;
+ selectIsLoadingEntries: (state: State) => boolean;
}
-export const createSummaryEpic = (): Epic<
+export const createEntriesEpic = () =>
+ combineEpics(
+ createEntriesEffectsEpic(),
+ loadEntriesEpic as EpicWithState,
+ loadMoreEntriesEpic as EpicWithState
+ );
+
+export const createEntriesEffectsEpic = (): Epic<
Action,
Action,
State,
- ManageStreamIntervalDependencies
+ ManageEntriesDependencies
> => (
action$,
state$,
{
- postToApi$,
- selectFirstEntry,
- selectLastEntry,
- selectEntriesStartLoadingState,
- selectEntriesEndLoadingState,
- selectSourceCoreFields,
- selectSourceIndices,
+ selectEntriesStart,
+ selectEntriesEnd,
+ selectHasMoreBeforeStart,
+ selectHasMoreAfterEnd,
+ selectIsLoadingEntries,
}
) => {
- const staleIntervalAfterJump$ = action$.pipe(
+ const shouldLoadAround$ = action$.pipe(
filter(targetActions.jumpToTarget.match),
- map(({ payload: target }) => target)
+ withLatestFrom(state$),
+ filter(([{ payload }, state]) => {
+ const entriesStart = selectEntriesStart(state);
+ const entriesEnd = selectEntriesEnd(state);
+
+ return entriesStart && entriesEnd
+ ? !timeKeyIsBetween(entriesStart, entriesEnd, payload)
+ : true;
+ }),
+ map(([{ payload }]) => pickTimeKey(payload))
);
- const staleIntervalAfterScroll$ = action$.pipe(
+ const shouldLoadMoreBefore$ = action$.pipe(
filter(reportVisibleEntries.match),
- debounceTime(VISIBLE_INTERVAL_SETTLE_TIMEOUT),
- map(({ payload: { middleKey } }) => middleKey),
- filter(middleKey => middleKey !== null)
+ filter(({ payload: { pagesBeforeStart } }) => pagesBeforeStart < DESIRED_BUFFER_PAGES),
+ withLatestFrom(state$),
+ filter(([action, state]) => !selectIsLoadingEntries(state)),
+ filter(([action, state]) => selectHasMoreBeforeStart(state)),
+ map(([action, state]) => selectEntriesStart(state)),
+ filter((entriesStart): entriesStart is TimeKey => entriesStart != null),
+ map(pickTimeKey)
);
- const missingStartEntriesAfterScroll$ = action$.pipe(
+ const shouldLoadMoreAfter$ = action$.pipe(
filter(reportVisibleEntries.match),
- map(({ payload: { pagesBeforeStart } }) =>
- Math.ceil(ASSUMED_ENTRIES_PER_PAGE * (DESIRED_BUFFER_PAGES - pagesBeforeStart))
- ),
- filter(missingEntries => missingEntries > 0)
- );
-
- const missingEndEntriesAfterScroll$ = action$.pipe(
- filter(reportVisibleEntries.match),
- map(({ payload: { pagesAfterEnd } }) =>
- Math.ceil(ASSUMED_ENTRIES_PER_PAGE * (DESIRED_BUFFER_PAGES - pagesAfterEnd))
- ),
- filter(missingEntries => missingEntries > 0)
- );
-
- const staleEndEntries$ = merge(
- action$.pipe(
- filter(startLiveStreaming.match),
- exhaustMap(() =>
- interval(3000).pipe(
- map(() => ({ isJump: false })),
- startWith({ isJump: true }),
- takeUntil(action$.pipe(filter(stopLiveStreaming.match)))
- )
- )
- ),
- action$.pipe(
- filter(() => false /* TODO: filter jumpToEnd */),
- map(() => ({ isJump: true }))
- )
- ).pipe(
- map(({ isJump }) => ({
- isJump,
- outdatedEntries: ASSUMED_ENTRIES_PER_PAGE * DESIRED_BUFFER_PAGES,
- }))
+ filter(({ payload: { pagesAfterEnd } }) => pagesAfterEnd < DESIRED_BUFFER_PAGES),
+ withLatestFrom(state$),
+ filter(([action, state]) => !selectIsLoadingEntries(state)),
+ filter(([action, state]) => selectHasMoreAfterEnd(state)),
+ map(([action, state]) => selectEntriesEnd(state)),
+ filter((entriesEnd): entriesEnd is TimeKey => entriesEnd != null),
+ map(pickTimeKey)
);
return merge(
- merge(
- staleIntervalAfterJump$,
- staleIntervalAfterScroll$.pipe(
- filter(() => {
- const state = state$.value;
- const startLoadingState = selectEntriesStartLoadingState(state);
- const endLoadingState = selectEntriesEndLoadingState(state);
-
- return (
- !isRunningLoadingProgress(startLoadingState.current) &&
- !isRunningLoadingProgress(endLoadingState.current)
- );
- })
- )
- ).pipe(
- withLatestFrom(postToApi$),
- switchMap(([target, postToApi]) => {
- const state = state$.value;
- const firstLogEntry = selectFirstEntry(state);
- const lastLogEntry = selectLastEntry(state);
-
- const isLocalJump =
- target !== null &&
- firstLogEntry !== null &&
- lastLogEntry !== null &&
- isBetween(firstLogEntry.fields, lastLogEntry.fields, target);
-
- // the interval is displayed symmetrically before and after the target
- const desiredEntriesPerEndpoint = Math.ceil(DEFAULT_INTERVAL_ENTRIES / 2);
-
- if (isLocalJump) {
- return [
- consolidateEntries({
- after: desiredEntriesPerEndpoint,
- before: desiredEntriesPerEndpoint,
- target: target!,
- }),
- ];
- } else if (target !== null) {
- return replaceEntries$(
- postToApi,
- target,
- desiredEntriesPerEndpoint,
- selectSourceIndices(state),
- selectSourceCoreFields(state)
- );
- } else {
- return [];
- }
- })
+ shouldLoadAround$.pipe(
+ exhaustMap(target => [
+ loadEntries({
+ sourceId: 'default',
+ timeKey: target,
+ countBefore: LOAD_CHUNK_SIZE,
+ countAfter: LOAD_CHUNK_SIZE,
+ }),
+ ])
),
- missingStartEntriesAfterScroll$.pipe(
- filter(() => {
- const state = state$.value;
- const startLoadingState = selectEntriesStartLoadingState(state);
- const endLoadingState = selectEntriesEndLoadingState(state);
-
- return (
- !isIntervalLoadingPolicy(endLoadingState.policy) &&
- !isRunningLoadingProgress(startLoadingState.current) &&
- !isExhaustedLoadingResult(startLoadingState.last) &&
- !isFailureLoadingResult(startLoadingState.last)
- );
- }),
- withLatestFrom(postToApi$),
- exhaustMap(([missingEntries, postToApi]) => {
- const state = state$.value;
- const firstLogEntry = selectFirstEntry(state);
-
- if (firstLogEntry === null) {
- return [];
- }
-
- const chunkSize = Math.max(MIN_CHUNK_SIZE, missingEntries);
- const target = getLogEntryKey(firstLogEntry);
- return extendEntriesStart$(
- postToApi,
- target,
- chunkSize,
- selectSourceIndices(state),
- selectSourceCoreFields(state)
- ).pipe(takeUntil(staleIntervalAfterJump$));
- })
+ shouldLoadMoreAfter$.pipe(
+ exhaustMap(target => [
+ loadMoreEntries({
+ sourceId: 'default',
+ timeKey: target,
+ countBefore: 0,
+ countAfter: LOAD_CHUNK_SIZE,
+ }),
+ ])
),
- missingEndEntriesAfterScroll$.pipe(
- filter(() => {
- const loadingState = selectEntriesEndLoadingState(state$.value);
-
- return (
- !isRunningLoadingProgress(loadingState.current) &&
- !isIntervalLoadingPolicy(loadingState.policy) &&
- !isExhaustedLoadingResult(loadingState.last) &&
- !isFailureLoadingResult(loadingState.last)
- );
- }),
- withLatestFrom(postToApi$),
- exhaustMap(([missingEntries, postToApi]) => {
- const state = state$.value;
- const lastLogEntry = selectLastEntry(state);
-
- if (lastLogEntry !== null) {
- return extendEntriesEnd$(
- postToApi,
- getLogEntryKey(lastLogEntry),
- Math.max(MIN_CHUNK_SIZE, missingEntries),
- selectSourceIndices(state),
- selectSourceCoreFields(state)
- ).pipe(takeUntil(staleIntervalAfterJump$));
- } else {
- return [];
- }
- })
- ),
- staleEndEntries$.pipe(
- withLatestFrom(postToApi$),
- exhaustMap(([{ isJump, outdatedEntries }, postToApi]) => {
- const state = state$.value;
-
- return replaceEntriesWithLatest$(
- postToApi,
- outdatedEntries,
- selectSourceIndices(state),
- selectSourceCoreFields(state),
- isJump
- ).pipe(takeUntil(staleIntervalAfterJump$));
- })
- ),
- staleIntervalAfterJump$.pipe(map(() => stopLiveStreaming()))
+ shouldLoadMoreBefore$.pipe(
+ exhaustMap(target => [
+ loadMoreEntries({
+ sourceId: 'default',
+ timeKey: target,
+ countBefore: LOAD_CHUNK_SIZE,
+ countAfter: 0,
+ }),
+ ])
+ )
);
};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/index.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/index.ts
index 52e3416900d75..c42bcef27fad9 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/index.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/index.ts
@@ -10,3 +10,4 @@ import * as entriesSelectors from './selectors';
export { entriesActions, entriesEpics, entriesSelectors };
export * from './reducer';
+export * from './state';
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_more_operation.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_more_operation.ts
new file mode 100644
index 0000000000000..de2d954f8ed48
--- /dev/null
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_more_operation.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { LogEntries as LogEntriesQuery } from '../../../../../common/graphql/types';
+import {
+ getLogEntryIndexAfterTime,
+ getLogEntryIndexBeforeTime,
+ getLogEntryKey,
+} from '../../../../utils/log_entry';
+import {
+ createGraphqlOperationActionCreators,
+ createGraphqlOperationReducer,
+ createGraphqlQueryEpic,
+} from '../../../../utils/remote_state/remote_graphql_state';
+import { logEntriesQuery } from './log_entries.gql_query';
+import { initialEntriesGraphqlState } from './state';
+
+const operationKey = 'load_more';
+
+export const loadMoreEntriesActionCreators = createGraphqlOperationActionCreators<
+ LogEntriesQuery.Query,
+ LogEntriesQuery.Variables
+>('entries', operationKey);
+
+export const loadMoreEntriesReducer = createGraphqlOperationReducer(
+ operationKey,
+ initialEntriesGraphqlState,
+ loadMoreEntriesActionCreators,
+ (state, action) => {
+ const logEntriesAround = action.payload.result.data.source.logEntriesAround;
+ const newEntries = logEntriesAround.entries;
+ const oldEntries = state && state.entries ? state.entries : [];
+ const oldStart = state && state.start ? state.start : null;
+ const oldEnd = state && state.end ? state.end : null;
+
+ if (newEntries.length <= 0) {
+ return state;
+ }
+
+ if ((action.payload.params.countBefore || 0) > 0) {
+ const lastLogEntry = newEntries[newEntries.length - 1];
+ const prependAtIndex = getLogEntryIndexAfterTime(oldEntries, getLogEntryKey(lastLogEntry));
+ return {
+ start: logEntriesAround.start,
+ end: oldEnd,
+ hasMoreBefore: logEntriesAround.hasMoreBefore,
+ hasMoreAfter: state ? state.hasMoreAfter : logEntriesAround.hasMoreAfter,
+ entries: [...newEntries, ...oldEntries.slice(prependAtIndex)],
+ };
+ } else if ((action.payload.params.countAfter || 0) > 0) {
+ const firstLogEntry = newEntries[0];
+ const appendAtIndex = getLogEntryIndexBeforeTime(oldEntries, getLogEntryKey(firstLogEntry));
+ return {
+ start: oldStart,
+ end: logEntriesAround.end,
+ hasMoreBefore: state ? state.hasMoreBefore : logEntriesAround.hasMoreBefore,
+ hasMoreAfter: logEntriesAround.hasMoreAfter,
+ entries: [...oldEntries.slice(0, appendAtIndex), ...newEntries],
+ };
+ } else {
+ return state;
+ }
+ }
+);
+
+export const loadMoreEntriesEpic = createGraphqlQueryEpic(
+ logEntriesQuery,
+ loadMoreEntriesActionCreators
+);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_operation.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_operation.ts
new file mode 100644
index 0000000000000..f26584d20aa82
--- /dev/null
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/load_operation.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { LogEntries as LogEntriesQuery } from '../../../../../common/graphql/types';
+import {
+ createGraphqlOperationActionCreators,
+ createGraphqlOperationReducer,
+ createGraphqlQueryEpic,
+} from '../../../../utils/remote_state/remote_graphql_state';
+import { logEntriesQuery } from './log_entries.gql_query';
+import { initialEntriesGraphqlState } from './state';
+
+const operationKey = 'load';
+
+export const loadEntriesActionCreators = createGraphqlOperationActionCreators<
+ LogEntriesQuery.Query,
+ LogEntriesQuery.Variables
+>('entries', operationKey);
+
+export const loadEntriesReducer = createGraphqlOperationReducer(
+ operationKey,
+ initialEntriesGraphqlState,
+ loadEntriesActionCreators,
+ (state, action) => action.payload.result.data.source.logEntriesAround
+);
+
+export const loadEntriesEpic = createGraphqlQueryEpic(logEntriesQuery, loadEntriesActionCreators);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/log_entries.gql_query.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/log_entries.gql_query.ts
new file mode 100644
index 0000000000000..1f3204f5169ce
--- /dev/null
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/log_entries.gql_query.ts
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import gql from 'graphql-tag';
+
+import { sharedFragments } from '../../../../../common/graphql/shared';
+
+export const logEntriesQuery = gql`
+ query LogEntries(
+ $sourceId: ID = "default"
+ $timeKey: InfraTimeKeyInput!
+ $countBefore: Int = 0
+ $countAfter: Int = 0
+ ) {
+ source(id: $sourceId) {
+ id
+ logEntriesAround(key: $timeKey, countBefore: $countBefore, countAfter: $countAfter) {
+ start {
+ ...InfraTimeKeyFields
+ }
+ end {
+ ...InfraTimeKeyFields
+ }
+ hasMoreBefore
+ hasMoreAfter
+ entries {
+ gid
+ key {
+ time
+ tiebreaker
+ }
+ message {
+ ... on InfraLogMessageFieldSegment {
+ field
+ value
+ }
+ ... on InfraLogMessageConstantSegment {
+ constant
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ${sharedFragments.InfraTimeKey}
+`;
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/reducer.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/reducer.ts
index bb221bc180573..f4d1a78829a4e 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/reducer.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/reducer.ts
@@ -4,206 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Action, combineReducers } from 'redux';
-import { reducerWithInitialState, reducerWithoutInitialState } from 'typescript-fsa-reducers';
+import reduceReducers from 'reduce-reducers';
+import { combineReducers, Reducer } from 'redux';
+import { reducerWithInitialState } from 'typescript-fsa-reducers';
import {
- getIndexNearLogEntry,
- getIndexOfLogEntry,
- getLogEntryKey,
- LogEntry,
- LogEntryTime,
-} from '../../../../../common/log_entry';
-import {
- createFailureResultReducer,
- createIdleProgressReducer,
- createRunningProgressReducer,
- createSuccessResultReducer,
- initialLoadingState,
- isSuccessLoadingResult,
- LoadingState,
-} from '../../../../utils/loading_state';
-import {
- consolidateEntries,
- extendEntriesEnd,
- extendEntriesStart,
- replaceEntries,
reportVisibleEntries,
- startLiveStreaming,
- stopLiveStreaming,
+ // startLiveStreaming,
+ // stopLiveStreaming,
} from './actions';
+import { loadMoreEntriesReducer } from './load_more_operation';
+import { loadEntriesReducer } from './load_operation';
+import { EntriesGraphqlState, EntriesState, initialEntriesState } from './state';
-interface EntriesLoadingParameters {
- count: number;
-}
-
-export interface EntriesState {
- start: LoadingState;
- end: LoadingState;
- entries: LogEntry[];
- visible: {
- startKey: LogEntryTime | null;
- middleKey: LogEntryTime | null;
- endKey: LogEntryTime | null;
- };
-}
-
-export const initialEntriesState: EntriesState = {
- end: initialLoadingState,
- entries: [],
- start: initialLoadingState,
- visible: {
- endKey: null,
- middleKey: null,
- startKey: null,
- },
-};
-
-const entriesStartCurrentProgressReducer = reducerWithInitialState(
- initialEntriesState.start.current
-)
- .cases([replaceEntries.started, extendEntriesStart.started], createRunningProgressReducer())
- .cases(
- [
- extendEntriesStart.done,
- extendEntriesStart.failed,
- replaceEntries.done,
- replaceEntries.failed,
- ],
- createIdleProgressReducer()
- );
-
-const entriesStartLastResultReducer = reducerWithInitialState(initialEntriesState.start.last)
- .case(
- replaceEntries.done,
- createSuccessResultReducer(({ count }, { logEntriesBefore }) => logEntriesBefore.length < count)
- )
- .case(
- extendEntriesStart.done,
- createSuccessResultReducer(({ count }, { logEntries }) => logEntries.length < count)
- )
- .cases([replaceEntries.failed, extendEntriesStart.failed], createFailureResultReducer());
-
-const entriesStartPolicyReducer = reducerWithInitialState(initialEntriesState.start.policy);
-
-const entriesStartReducer = combineReducers({
- current: entriesStartCurrentProgressReducer,
- last: entriesStartLastResultReducer,
- policy: entriesStartPolicyReducer,
-});
-
-const entriesEndCurrentProgressReducer = reducerWithInitialState(initialEntriesState.end.current)
- .cases([replaceEntries.started, extendEntriesEnd.started], createRunningProgressReducer())
- .cases(
- [extendEntriesEnd.done, extendEntriesEnd.failed, replaceEntries.done, replaceEntries.failed],
- createIdleProgressReducer()
- );
-
-const entriesEndLastResultReducer = reducerWithInitialState(initialEntriesState.end.last)
- .case(
- replaceEntries.done,
- createSuccessResultReducer(({ count }, { logEntriesAfter }) => logEntriesAfter.length < count)
- )
- .case(
- extendEntriesEnd.done,
- createSuccessResultReducer(({ count }, { logEntries }) => logEntries.length < count - 1)
- )
- .cases([replaceEntries.failed, extendEntriesEnd.failed], createFailureResultReducer());
-
-const entriesEndPolicyReducer = reducerWithInitialState(initialEntriesState.end.policy)
- .case(startLiveStreaming, () => ({
- delayMillis: 5000,
- policy: 'interval',
- }))
- .case(stopLiveStreaming, () => ({
- policy: 'manual',
- }));
-
-const entriesEndReducer = combineReducers({
- current: entriesEndCurrentProgressReducer,
- last: entriesEndLastResultReducer,
- policy: entriesEndPolicyReducer,
-});
-
-const entriesEntriesReducer = reducerWithInitialState(initialEntriesState.entries)
- .case(replaceEntries.started, (state, { clearEagerly }) => (clearEagerly ? [] : state))
- .case(
- replaceEntries.done,
- (state, { params: { clearEagerly }, result: { logEntriesBefore, logEntriesAfter } }) =>
- clearEagerly
- ? [...logEntriesBefore, ...logEntriesAfter]
- : [...logEntriesBefore, ...logEntriesAfter].map(logEntry => {
- const oldLogEntryIndex = getIndexOfLogEntry(state, getLogEntryKey(logEntry));
- if (oldLogEntryIndex) {
- const oldLogEntry = state[oldLogEntryIndex];
- if (oldLogEntry.origin.id === logEntry.origin.id) {
- return oldLogEntry;
- }
- }
- return logEntry;
- })
- )
- .case(extendEntriesStart.done, (state, { result: { logEntries } }) => {
- if (logEntries.length > 0) {
- const lastLogEntry = logEntries[logEntries.length - 1];
- const prependAtIndex = getIndexNearLogEntry(state, getLogEntryKey(lastLogEntry), true);
- return [...logEntries, ...state.slice(prependAtIndex)];
- } else {
- return state;
- }
- })
- .case(extendEntriesEnd.done, (state, { result: { logEntries } }) => {
- if (logEntries.length > 0) {
- const firstLogEntry = logEntries[0];
- const appendAtIndex = getIndexNearLogEntry(state, getLogEntryKey(firstLogEntry));
- return [...state.slice(0, appendAtIndex), ...logEntries];
- } else {
- return state;
- }
- });
-
-const entriesCrossSliceReducer = reducerWithoutInitialState().case(
- consolidateEntries,
- (state, { after, before, target }) => {
- const { start, end, entries } = state;
- const targetIndex = getIndexNearLogEntry(entries, target);
-
- if (targetIndex === null) {
- return state;
- }
-
- const startIndex = Math.max(targetIndex - before, 0);
- const endIndex = Math.min(targetIndex + after, entries.length);
- const consolidatedLogEntries = entries.slice(startIndex, endIndex);
- const newStartLoadingState: typeof start =
- startIndex > 0 && isSuccessLoadingResult(start.last)
- ? {
- ...start,
- last: {
- ...start.last,
- isExhausted: false,
- },
- }
- : start;
- const newEndLoadingState: typeof end =
- endIndex < entries.length && isSuccessLoadingResult(end.last)
- ? {
- ...end,
- last: {
- ...end.last,
- isExhausted: false,
- },
- }
- : end;
-
- return {
- ...state,
- end: newEndLoadingState,
- entries: consolidatedLogEntries,
- start: newStartLoadingState,
- };
- }
-);
+const entriesEntriesReducer = reduceReducers(loadEntriesReducer, loadMoreEntriesReducer) as Reducer<
+ EntriesGraphqlState
+>;
const entriesVisibleReducer = reducerWithInitialState(initialEntriesState.visible).case(
reportVisibleEntries,
@@ -214,19 +30,7 @@ const entriesVisibleReducer = reducerWithInitialState(initialEntriesState.visibl
})
);
-const combinedEntriesSliceReducer = combineReducers({
- end: entriesEndReducer,
+export const entriesReducer = combineReducers({
entries: entriesEntriesReducer,
- start: entriesStartReducer,
visible: entriesVisibleReducer,
});
-
-export const entriesReducer = (
- state: EntriesState = initialEntriesState,
- action: Action
-): EntriesState => {
- const updatedSliceState = combinedEntriesSliceReducer(state, action);
- const updatedCrossSliceState = entriesCrossSliceReducer(updatedSliceState, action);
-
- return updatedCrossSliceState;
-};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/selectors.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/selectors.ts
index 8d03837c82283..f37b5032ae4ce 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/selectors.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/selectors.ts
@@ -6,20 +6,65 @@
import { createSelector } from 'reselect';
-import { getIndexOfLogEntry, LogEntry, LogEntryTime } from '../../../../../common/log_entry';
-import { EntriesState } from './reducer';
+import { TimeKey } from '../../../../../common/time';
+import { getLogEntryIndexAtTime, LogEntry } from '../../../../utils/log_entry';
+import { createGraphqlStateSelectors } from '../../../../utils/remote_state/remote_graphql_state';
+import { EntriesGraphqlState, EntriesState } from './state';
-const getEntry = (entries: LogEntry[], entryKey: LogEntryTime) => {
- const entryIndex = getIndexOfLogEntry(entries, entryKey);
+const entriesGraphlStateSelectors = createGraphqlStateSelectors(
+ (state: EntriesState) => state.entries
+);
+
+const getEntry = (entries: LogEntry[], entryKey: TimeKey) => {
+ const entryIndex = getLogEntryIndexAtTime(entries, entryKey);
return entryIndex !== null ? entries[entryIndex] : null;
};
-export const selectEntries = (state: EntriesState) => state.entries;
+export const selectEntries = createSelector(
+ entriesGraphlStateSelectors.selectData,
+ data => (data ? data.entries : [])
+);
+
+export const selectIsLoadingEntries = entriesGraphlStateSelectors.selectIsLoading;
+
+export const selectIsReloadingEntries = createSelector(
+ entriesGraphlStateSelectors.selectIsLoading,
+ entriesGraphlStateSelectors.selectLoadingProgressOperationInfo,
+ (isLoading, operationInfo) =>
+ isLoading && operationInfo ? operationInfo.operationKey === 'load' : false
+);
+
+export const selectIsLoadingMoreEntries = createSelector(
+ entriesGraphlStateSelectors.selectIsLoading,
+ entriesGraphlStateSelectors.selectLoadingProgressOperationInfo,
+ (isLoading, operationInfo) =>
+ isLoading && operationInfo ? operationInfo.operationKey === 'load_more' : false
+);
+
+export const selectEntriesStart = createSelector(
+ entriesGraphlStateSelectors.selectData,
+ data => (data && data.start ? data.start : null)
+);
-export const selectEntriesStartLoadingState = (state: EntriesState) => state.start;
+export const selectEntriesEnd = createSelector(
+ entriesGraphlStateSelectors.selectData,
+ data => (data && data.end ? data.end : null)
+);
-export const selectEntriesEndLoadingState = (state: EntriesState) => state.end;
+export const selectHasMoreBeforeStart = createSelector(
+ entriesGraphlStateSelectors.selectData,
+ data => (data ? data.hasMoreBefore : true)
+);
+
+export const selectHasMoreAfterEnd = createSelector(
+ entriesGraphlStateSelectors.selectData,
+ data => (data ? data.hasMoreAfter : true)
+);
+
+export const selectEntriesStartLoadingState = entriesGraphlStateSelectors.selectLoadingState;
+
+export const selectEntriesEndLoadingState = entriesGraphlStateSelectors.selectLoadingState;
export const selectFirstEntry = createSelector(
selectEntries,
@@ -32,11 +77,10 @@ export const selectLastEntry = createSelector(
);
export const selectLoadedEntriesTimeInterval = createSelector(
- selectFirstEntry,
- selectLastEntry,
- (firstEntry, lastEntry) => ({
- end: lastEntry ? lastEntry.fields.time : null,
- start: firstEntry ? firstEntry.fields.time : null,
+ entriesGraphlStateSelectors.selectData,
+ data => ({
+ end: data && data.end ? data.end.time : null,
+ start: data && data.start ? data.start.time : null,
})
);
@@ -65,8 +109,8 @@ export const selectVisibleEntriesTimeInterval = createSelector(
selectFirstVisibleEntry,
selectLastVisibleEntry,
(firstVisibleEntry, lastVisibleEntry) => ({
- end: lastVisibleEntry ? lastVisibleEntry.fields.time : null,
- start: firstVisibleEntry ? firstVisibleEntry.fields.time : null,
+ end: lastVisibleEntry ? lastVisibleEntry.key.time : null,
+ start: firstVisibleEntry ? firstVisibleEntry.key.time : null,
})
);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/state.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/state.ts
new file mode 100644
index 0000000000000..750d355a612fd
--- /dev/null
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/state.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { InfraTimeKey, LogEntries as LogEntriesQuery } from '../../../../../common/graphql/types';
+import { createGraphqlInitialState } from '../../../../utils/remote_state/remote_graphql_state';
+
+export type EntriesGraphqlState = typeof initialEntriesGraphqlState;
+
+export interface EntriesState {
+ entries: EntriesGraphqlState;
+ visible: {
+ startKey: InfraTimeKey | null;
+ middleKey: InfraTimeKey | null;
+ endKey: InfraTimeKey | null;
+ };
+}
+
+export const initialEntriesGraphqlState = createGraphqlInitialState<
+ LogEntriesQuery.LogEntriesAround
+>();
+
+export const initialEntriesState: EntriesState = {
+ entries: initialEntriesGraphqlState,
+ visible: {
+ endKey: null,
+ middleKey: null,
+ startKey: null,
+ },
+};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/epics.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/epics.ts
index b57392261c031..e585669757dc8 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/epics.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/epics.ts
@@ -7,14 +7,14 @@
import { combineEpics } from 'redux-observable';
import { entriesEpics } from './entries';
-import { searchResultsEpics } from './search_results';
-import { searchSummaryEpics } from './search_summary';
+// import { searchResultsEpics } from './search_results';
+// import { searchSummaryEpics } from './search_summary';
import { summaryEpics } from './summary';
export const createRootEpic = () =>
combineEpics(
summaryEpics.createSummaryEpic(),
- entriesEpics.createSummaryEpic(),
- searchResultsEpics.createSearchResultsEpic(),
- searchSummaryEpics.createSearchSummaryEpic()
+ entriesEpics.createEntriesEpic()
+ // searchResultsEpics.createSearchResultsEpic(),
+ // searchSummaryEpics.createSearchSummaryEpic()
);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/search_results/epics.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/search_results/epics.ts
index 055cf6ac2375a..7dda10972ba70 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/search_results/epics.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/search_results/epics.ts
@@ -9,7 +9,7 @@ import { Epic } from 'redux-observable';
import { concat, merge } from 'rxjs';
import { concatMap, filter, takeUntil, withLatestFrom } from 'rxjs/operators';
-import { getLogEntryKey, LogEntry } from '../../../../../common/log_entry';
+import { getLogEntryKey, LogEntry } from '../../../../utils/log_entry';
import { entriesActions } from '../entries';
import { searchActions } from '../search';
import { CommonFetchSearchResultsDependencies } from './api/fetch_search_results';
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
index 409ac73549f63..8043fa86fa87d 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
@@ -6,7 +6,7 @@
import { createSelector } from 'reselect';
-import { getLogEntryKey } from '../../../../common/log_entry';
+import { getLogEntryKey } from '../../../utils/log_entry';
import {
getSearchResultIndexAfterTime,
getSearchResultIndexBeforeTime,
@@ -118,13 +118,13 @@ export const sharedSelectors = {
entriesSelectors.selectFirstVisibleEntry,
entriesSelectors.selectLastVisibleEntry,
targetSelectors.selectTarget,
- (firstVisibleEntry, lastVisibleLEntry, target) => {
- if (firstVisibleEntry && lastVisibleLEntry) {
- return (firstVisibleEntry.fields.time + lastVisibleLEntry.fields.time) / 2;
+ (firstVisibleEntry, lastVisibleEntry, target) => {
+ if (firstVisibleEntry && lastVisibleEntry) {
+ return (firstVisibleEntry.key.time + lastVisibleEntry.key.time) / 2;
} else if (firstVisibleEntry) {
- return firstVisibleEntry.fields.time;
- } else if (lastVisibleLEntry) {
- return lastVisibleLEntry.fields.time;
+ return firstVisibleEntry.key.time;
+ } else if (lastVisibleEntry) {
+ return lastVisibleEntry.key.time;
} else {
return target.time;
}
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/source/reducer.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/source/reducer.ts
index 571474bb32afd..0f9e2f0aef89c 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/source/reducer.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/source/reducer.ts
@@ -6,11 +6,11 @@
export const initialSourceState: SourceState = {
coreFields: {
- message: '@message',
+ message: 'message',
tiebreaker: '_doc',
time: '@timestamp',
},
- indices: ['logstash-*'],
+ indices: ['xpack-infra-default-logs'],
name: 'Unnamed Source',
};
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/with_stream_items.ts b/x-pack/plugins/infra/public/containers/logging_legacy/with_stream_items.ts
index dc6791add056e..d85f1ed175863 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/with_stream_items.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/with_stream_items.ts
@@ -7,10 +7,7 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
-import { LogEntry } from '../../../common/log_entry';
import { SearchResult } from '../../../common/log_search_result';
-import { bindPlainActionCreators } from '../../utils/typed_redux';
-
import {
entriesActions,
entriesSelectors,
@@ -18,17 +15,17 @@ import {
State,
targetActions,
targetSelectors,
- textviewSelectors,
} from '../../containers/logging_legacy/state';
+import { LogEntry, LogEntryMessageSegment } from '../../utils/log_entry';
+import { asChildFunctionRenderer } from '../../utils/typed_react';
+import { bindPlainActionCreators } from '../../utils/typed_redux';
export const withStreamItems = connect(
(state: State) => ({
endLoadingState: entriesSelectors.selectEntriesEndLoadingState(state),
items: selectItems(state),
- scale: textviewSelectors.selectTextviewScale(state),
startLoadingState: entriesSelectors.selectEntriesStartLoadingState(state),
target: targetSelectors.selectTarget(state),
- wrap: textviewSelectors.selectTextviewWrap(state),
}),
bindPlainActionCreators({
jumpToTarget: targetActions.jumpToTarget,
@@ -36,17 +33,41 @@ export const withStreamItems = connect(
})
);
+export const WithStreamItems = asChildFunctionRenderer(withStreamItems);
+
const selectItems = createSelector(
entriesSelectors.selectEntries,
+ entriesSelectors.selectIsReloadingEntries,
searchResultsSelectors.selectSearchResultsById,
- (logEntries, searchResults) =>
- logEntries.map(logEntry =>
- createLogEntryStreamItem(logEntry, searchResults[logEntry.gid] || null)
- )
+ (logEntries, isReloading, searchResults) =>
+ isReloading
+ ? []
+ : logEntries.map(logEntry =>
+ createLogEntryStreamItem(logEntry, searchResults[logEntry.gid] || null)
+ )
);
const createLogEntryStreamItem = (logEntry: LogEntry, searchResult?: SearchResult) => ({
kind: 'logEntry' as 'logEntry',
- logEntry,
+ logEntry: {
+ gid: logEntry.gid,
+ origin: {
+ id: logEntry.gid,
+ index: '',
+ type: '',
+ },
+ fields: {
+ time: logEntry.key.time,
+ tiebreaker: logEntry.key.tiebreaker,
+ message: logEntry.message.map(formatMessageSegment).join(' '),
+ },
+ },
searchResult,
});
+
+const formatMessageSegment = (messageSegment: LogEntryMessageSegment): string =>
+ messageSegment.__typename === 'InfraLogMessageFieldSegment'
+ ? messageSegment.value
+ : messageSegment.__typename === 'InfraLogMessageConstantSegment'
+ ? messageSegment.constant
+ : 'failed to format message';
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/with_text_scale_controls_props.ts b/x-pack/plugins/infra/public/containers/logging_legacy/with_text_scale_controls_props.ts
index b27f07b12e9f5..4b64bc531845e 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/with_text_scale_controls_props.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/with_text_scale_controls_props.ts
@@ -4,23 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/
-/**
- * Temporary Workaround
- * This is not a well-designed container. It only exists to enable quick
- * migration of the redux-based logging ui into the infra-ui codebase. It will
- * be removed during the refactoring to graphql/apollo.
- */
import { connect } from 'react-redux';
+import { TextScale } from '../../../common/log_text_scale';
+import { asChildFunctionRenderer } from '../../utils/typed_react';
import { bindPlainActionCreators } from '../../utils/typed_redux';
import { State, textviewActions, textviewSelectors } from './state';
-export const withTextScaleControlsProps = connect(
+export const withTextScale = connect(
(state: State) => ({
- availableTextScales: ['large', 'medium', 'small'],
+ availableTextScales: ['large', 'medium', 'small'] as TextScale[],
textScale: textviewSelectors.selectTextviewScale(state),
}),
bindPlainActionCreators({
setTextScale: textviewActions.setTextviewScale,
})
);
+
+export const WithTextScale = asChildFunctionRenderer(withTextScale);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/with_text_wrap_controls_props.ts b/x-pack/plugins/infra/public/containers/logging_legacy/with_text_wrap_controls_props.ts
index 3790b1637633f..5c7519eec0a5e 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/with_text_wrap_controls_props.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/with_text_wrap_controls_props.ts
@@ -4,18 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
-/**
- * Temporary Workaround
- * This is not a well-designed container. It only exists to enable quick
- * migration of the redux-based logging ui into the infra-ui codebase. It will
- * be removed during the refactoring to graphql/apollo.
- */
import { connect } from 'react-redux';
+import { asChildFunctionRenderer } from '../../utils/typed_react';
import { bindPlainActionCreators } from '../../utils/typed_redux';
import { State, textviewActions, textviewSelectors } from './state';
-export const withTextWrapControlsProps = connect(
+export const withTextWrap = connect(
(state: State) => ({
wrap: textviewSelectors.selectTextviewWrap(state),
}),
@@ -23,3 +18,5 @@ export const withTextWrapControlsProps = connect(
setTextWrap: textviewActions.setTextviewWrap,
})
);
+
+export const WithTextWrap = asChildFunctionRenderer(withTextWrap);
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/with_time_controls_props.ts b/x-pack/plugins/infra/public/containers/logging_legacy/with_time_controls_props.ts
index c5aff37f9a8b6..794b8da969971 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/with_time_controls_props.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/with_time_controls_props.ts
@@ -7,10 +7,11 @@
import { connect } from 'react-redux';
import { isIntervalLoadingPolicy } from '../../utils/loading_state';
+import { asChildFunctionRenderer } from '../../utils/typed_react';
import { bindPlainActionCreators } from '../../utils/typed_redux';
import { entriesActions, entriesSelectors, sharedSelectors, State, targetActions } from './state';
-export const withTimeControlsProps = connect(
+export const withTimeControls = connect(
(state: State) => ({
currentTime: sharedSelectors.selectVisibleMidpointOrTargetTime(state),
isLiveStreaming: isIntervalLoadingPolicy(
@@ -23,3 +24,5 @@ export const withTimeControlsProps = connect(
jumpToTime: targetActions.jumpToTime,
})
);
+
+export const WithTimeControls = asChildFunctionRenderer(withTimeControls);
diff --git a/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts b/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
index 4c27e0e45fa1d..7693a8bc9b34e 100644
--- a/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
+++ b/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
@@ -16,17 +16,24 @@ import { InfraAxiosApiAdapter } from '../adapters/api/axios_api_adapter';
import { InfraKibanaObservableApiAdapter } from '../adapters/observable_api/kibana_observable_api';
import { InfraFieldsDomain } from '../domains/fields_domain';
+import introspectionQueryResultData from '../../../common/graphql/introspection.json';
import { InfraKibanaFrameworkAdapter } from '../adapters/framework/kibana_framework_adapter';
import { InfraFrontendLibs } from '../lib';
-import { InMemoryCache } from 'apollo-cache-inmemory';
+import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import ApolloClient from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { withClientState } from 'apollo-link-state';
+import { printSchema } from 'graphql';
+import { buildSchemaFromTypeDefinitions } from 'graphql-tools';
export function compose(): InfraFrontendLibs {
- const cache = new InMemoryCache();
+ const cache = new InMemoryCache({
+ fragmentMatcher: new IntrospectionFragmentMatcher({
+ introspectionQueryResultData,
+ }),
+ });
const observableApi = new InfraKibanaObservableApiAdapter({
basePath: chrome.getBasePath(),
@@ -38,10 +45,7 @@ export function compose(): InfraFrontendLibs {
link: ApolloLink.from([
withClientState({
cache,
- resolvers: {
- Mutation: {},
- Query: {},
- },
+ resolvers: {},
}),
new HttpLink({
credentials: 'same-origin',
diff --git a/x-pack/plugins/infra/public/lib/lib.d.ts b/x-pack/plugins/infra/public/lib/lib.d.ts
index ae1340427199e..32fc414450e1f 100644
--- a/x-pack/plugins/infra/public/lib/lib.d.ts
+++ b/x-pack/plugins/infra/public/lib/lib.d.ts
@@ -17,12 +17,14 @@ export interface InfraFrontendLibs {
framework: InfraFrameworkAdapter;
fields: InfraFieldsDomain;
api: InfraApiAdapter;
- apolloClient: ApolloClient;
+ apolloClient: InfraApolloClient;
observableApi: InfraObservableApi;
}
export type InfraTimezoneProvider = () => string;
+export type InfraApolloClient = ApolloClient;
+
export interface InfraFrameworkAdapter {
// Instance vars
appState?: object;
diff --git a/x-pack/plugins/infra/public/pages/logs/logs.tsx b/x-pack/plugins/infra/public/pages/logs/logs.tsx
index e4fc409393dbb..cc5712f49ae4e 100644
--- a/x-pack/plugins/infra/public/pages/logs/logs.tsx
+++ b/x-pack/plugins/infra/public/pages/logs/logs.tsx
@@ -30,27 +30,20 @@ import { LogTextWrapControls } from '../../components/logging/log_text_wrap_cont
import { LogTimeControls } from '../../components/logging/log_time_controls';
import { withLibs } from '../../containers/libs';
-import { State } from '../../containers/logging_legacy/state';
+import { State, targetActions } from '../../containers/logging_legacy/state';
import { withLogSearchControlsProps } from '../../containers/logging_legacy/with_log_search_controls_props';
import { withMinimapProps } from '../../containers/logging_legacy/with_minimap_props';
import { withMinimapScaleControlsProps } from '../../containers/logging_legacy/with_minimap_scale_controls_props';
-import { withStreamItems } from '../../containers/logging_legacy/with_stream_items';
-import { withTextScaleControlsProps } from '../../containers/logging_legacy/with_text_scale_controls_props';
-import { withTextStreamScrollState } from '../../containers/logging_legacy/with_text_stream_scroll_state';
-import { withTextWrapControlsProps } from '../../containers/logging_legacy/with_text_wrap_controls_props';
-import { withTimeControlsProps } from '../../containers/logging_legacy/with_time_controls_props';
+import { WithStreamItems } from '../../containers/logging_legacy/with_stream_items';
+import { WithTextScale } from '../../containers/logging_legacy/with_text_scale_controls_props';
+import { WithTextWrap } from '../../containers/logging_legacy/with_text_wrap_controls_props';
+import { WithTimeControls } from '../../containers/logging_legacy/with_time_controls_props';
import { withVisibleLogEntries } from '../../containers/logging_legacy/with_visible_log_entries';
const ConnectedLogMinimap = withMinimapProps(LogMinimap);
const ConnectedLogMinimapScaleControls = withMinimapScaleControlsProps(LogMinimapScaleControls);
const ConnectedLogPositionText = withVisibleLogEntries(LogPositionText);
const ConnectedLogSearchControls = withLogSearchControlsProps(LogSearchControls);
-const ConnectedLogTextScaleControls = withTextScaleControlsProps(LogTextScaleControls);
-const ConnectedLogTextWrapControls = withTextWrapControlsProps(LogTextWrapControls);
-const ConnectedTimeControls = withTimeControlsProps(LogTimeControls);
-const ConnectedScrollableLogTextStreamView = withStreamItems(
- withTextStreamScrollState(ScrollableLogTextStreamView)
-);
interface LogsPageProps {
libs: InfraFrontendLibs;
@@ -70,6 +63,7 @@ export const LogsPage = withLibs(
const libs = new BehaviorSubject(props.libs);
const store = createStore({
+ apolloClient: libs.pipe(pluck('apolloClient')),
observableApi: libs.pipe(pluck('observableApi')),
});
@@ -85,6 +79,15 @@ export const LogsPage = withLibs(
}
}
+ public componentDidMount() {
+ this.state.store.dispatch(
+ targetActions.jumpToTarget({
+ time: Date.now(),
+ tiebreaker: 0,
+ })
+ );
+ }
+
public render() {
return (
@@ -98,12 +101,26 @@ export const LogsPage = withLibs(
-
-
+
+ {({ wrap, setTextWrap }) => (
+
+ )}
+
+
+ {({ availableTextScales, textScale, setTextScale }) => (
+
+ )}
+
-
+
+ {timeProps => }
+
@@ -111,7 +128,25 @@ export const LogsPage = withLibs(
{({ measureRef, content: { width = 0, height = 0 } }) => (
-
+
+ {({ textScale }) => (
+
+ {({ wrap }) => (
+
+ {streamItemsProps => (
+
+ )}
+
+ )}
+
+ )}
+
)}
diff --git a/x-pack/plugins/infra/public/pages/logs/store.ts b/x-pack/plugins/infra/public/pages/logs/store.ts
index c91e36f8ab14f..98723e39733b4 100644
--- a/x-pack/plugins/infra/public/pages/logs/store.ts
+++ b/x-pack/plugins/infra/public/pages/logs/store.ts
@@ -14,13 +14,13 @@ import {
entriesSelectors,
initialState,
reducer,
- searchSelectors,
+ // searchSelectors,
sourceSelectors,
State,
summarySelectors,
targetSelectors,
} from '../../containers/logging_legacy/state';
-import { InfraObservableApi } from '../../lib/lib';
+import { InfraApolloClient, InfraObservableApi } from '../../lib/lib';
declare global {
interface Window {
@@ -29,21 +29,28 @@ declare global {
}
export interface StoreDependencies {
+ apolloClient: Observable;
observableApi: Observable;
}
-export function createStore({ observableApi }: StoreDependencies) {
+export function createStore({ apolloClient, observableApi }: StoreDependencies) {
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const middlewareDependencies = {
postToApi$: observableApi.pipe(map(({ post }) => post)),
- selectEntriesEndLoadingState: entriesSelectors.selectEntriesEndLoadingState,
- selectEntriesStartLoadingState: entriesSelectors.selectEntriesStartLoadingState,
- selectFirstEntry: entriesSelectors.selectFirstEntry,
+ apolloClient$: apolloClient,
+ selectIsLoadingEntries: entriesSelectors.selectIsLoadingEntries,
+ selectEntriesEnd: entriesSelectors.selectEntriesEnd,
+ selectEntriesStart: entriesSelectors.selectEntriesStart,
+ selectHasMoreAfterEnd: entriesSelectors.selectHasMoreAfterEnd,
+ selectHasMoreBeforeStart: entriesSelectors.selectHasMoreBeforeStart,
+ // selectEntriesEndLoadingState: entriesSelectors.selectEntriesEndLoadingState,
+ // selectEntriesStartLoadingState: entriesSelectors.selectEntriesStartLoadingState,
+ // selectFirstEntry: entriesSelectors.selectFirstEntry,
selectFirstSummaryBucket: summarySelectors.selectFirstSummaryBucket,
- selectLastEntry: entriesSelectors.selectLastEntry,
+ // selectLastEntry: entriesSelectors.selectLastEntry,
selectLastSummaryBucket: summarySelectors.selectLastSummaryBucket,
- selectQuery: searchSelectors.selectQuery,
+ // selectQuery: searchSelectors.selectQuery,
selectSourceCoreFields: sourceSelectors.selectSourceCoreFields,
selectSourceIndices: sourceSelectors.selectSourceIndices,
selectSummaryBucketSize: summarySelectors.selectSummaryBucketSize,
diff --git a/x-pack/plugins/infra/public/utils/loading_state/index.ts b/x-pack/plugins/infra/public/utils/loading_state/index.ts
index 0aa0b517f7b84..d4a1b8e52ad00 100644
--- a/x-pack/plugins/infra/public/utils/loading_state/index.ts
+++ b/x-pack/plugins/infra/public/utils/loading_state/index.ts
@@ -6,21 +6,25 @@
export { initialLoadingState, LoadingState } from './loading_state';
-export { isManualLoadingPolicy, isIntervalLoadingPolicy } from './loading_policy';
+export { isManualLoadingPolicy, isIntervalLoadingPolicy, LoadingPolicy } from './loading_policy';
export {
createRunningProgressReducer,
createIdleProgressReducer,
- isUninitializedLoadingProgress,
+ isIdleLoadingProgress,
isRunningLoadingProgress,
+ LoadingProgress,
} from './loading_progress';
export {
- createSuccessResultReducer,
+ createFailureResult,
createFailureResultReducer,
- isUninitializedLoadingResult,
- isSuccessLoadingResult,
- isFailureLoadingResult,
- isExhaustedLoadingResult,
+ createSuccessResult,
+ createSuccessResultReducer,
getTimeOrDefault,
+ isExhaustedLoadingResult,
+ isFailureLoadingResult,
+ isSuccessLoadingResult,
+ isUninitializedLoadingResult,
+ LoadingResult,
} from './loading_result';
diff --git a/x-pack/plugins/infra/public/utils/loading_state/loading_progress.ts b/x-pack/plugins/infra/public/utils/loading_state/loading_progress.ts
index 891a42c464f2d..8e2b09ee5f1f5 100644
--- a/x-pack/plugins/infra/public/utils/loading_state/loading_progress.ts
+++ b/x-pack/plugins/infra/public/utils/loading_state/loading_progress.ts
@@ -16,7 +16,7 @@ interface RunningLoadingProgress {
export type LoadingProgress = IdleLoadingProgress | RunningLoadingProgress;
-export const isUninitializedLoadingProgress = (
+export const isIdleLoadingProgress =
(
loadingProgress: LoadingProgress
): loadingProgress is IdleLoadingProgress => loadingProgress.progress === 'idle';
diff --git a/x-pack/plugins/infra/public/utils/loading_state/loading_result.ts b/x-pack/plugins/infra/public/utils/loading_state/loading_result.ts
index da16b0f251469..e48b04743c811 100644
--- a/x-pack/plugins/infra/public/utils/loading_state/loading_result.ts
+++ b/x-pack/plugins/infra/public/utils/loading_state/loading_result.ts
@@ -53,26 +53,36 @@ export const getTimeOrDefault: GetTimeOrDefaultT =
(
defaultValue?: T
) => (isUninitializedLoadingResult(loadingResult) ? defaultValue || null : loadingResult.time);
-export const createSuccessResultReducer = (
- isExhausted: (params: Parameters, result: Payload) => boolean
-) => (
- state: LoadingResult,
- { params, result }: { params: Parameters; result: Payload }
+export const createSuccessResult = (
+ parameters: Parameters,
+ isExhausted: boolean
): SuccessLoadingResult => ({
- isExhausted: isExhausted(params, result),
- parameters: params,
+ isExhausted,
+ parameters,
result: 'success',
time: Date.now(),
});
-export const createFailureResultReducer = (
- convertErrorToString: (error: ErrorPayload) => string = error => `${error}`
+export const createSuccessResultReducer = (
+ isExhausted: (params: Parameters, result: Payload) => boolean
) => (
state: LoadingResult,
- { params, error }: { params: Parameters; error: ErrorPayload }
+ { params, result }: { params: Parameters; result: Payload }
+): SuccessLoadingResult => createSuccessResult(params, isExhausted(params, result));
+
+export const createFailureResult = (
+ parameters: Parameters,
+ reason: string
): FailureLoadingResult => ({
- parameters: params,
- reason: convertErrorToString(error),
+ parameters,
+ reason,
result: 'failure',
time: Date.now(),
});
+
+export const createFailureResultReducer = (
+ convertErrorToString: (error: ErrorPayload) => string = error => `${error}`
+) => (
+ state: LoadingResult,
+ { params, error }: { params: Parameters; error: ErrorPayload }
+): FailureLoadingResult => createFailureResult(params, convertErrorToString(error));
diff --git a/x-pack/plugins/infra/public/utils/log_entry/index.ts b/x-pack/plugins/infra/public/utils/log_entry/index.ts
new file mode 100644
index 0000000000000..66cc5108b6692
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/log_entry/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export * from './log_entry';
diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts b/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
new file mode 100644
index 0000000000000..30de10c710180
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { bisector } from 'd3-array';
+
+import { LogEntries as LogEntriesQuery } from '../../../common/graphql/types';
+import {
+ compareTimeKeys,
+ compareToTimeKey,
+ getIndexAtTimeKey,
+ TimeKey,
+} from '../../../common/time';
+
+export type LogEntry = LogEntriesQuery.Entries;
+
+export type LogEntryMessageSegment = LogEntriesQuery.Message;
+
+export const getLogEntryKey = (entry: LogEntry) => entry.key;
+
+const logEntryTimeBisector = bisector(compareToTimeKey(getLogEntryKey));
+
+export const getLogEntryIndexBeforeTime = logEntryTimeBisector.left;
+export const getLogEntryIndexAfterTime = logEntryTimeBisector.right;
+export const getLogEntryIndexAtTime = getIndexAtTimeKey(getLogEntryKey);
diff --git a/x-pack/plugins/infra/public/utils/memoize_last.ts b/x-pack/plugins/infra/public/utils/memoize_last.ts
new file mode 100644
index 0000000000000..fbab4ce22cf6e
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/memoize_last.ts
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+interface MemoizedCall {
+ args: any[];
+ returnValue: any;
+ this: any;
+}
+
+// A symbol expressing, that the memoized function has never been called
+const neverCalled: unique symbol = Symbol();
+type NeverCalled = typeof neverCalled;
+
+/**
+ * A simple memoize function, that only stores the last returned value
+ * and uses the identity of all passed parameters as a cache key.
+ */
+function memoizeLast any>(func: T): T {
+ let prevCall: MemoizedCall | NeverCalled = neverCalled;
+
+ // We need to use a `function` here for proper this passing.
+ // tslint:disable-next-line:only-arrow-functions
+ const memoizedFunction = function(this: any, ...args: any[]) {
+ if (
+ prevCall !== neverCalled &&
+ prevCall.this === this &&
+ prevCall.args.length === args.length &&
+ prevCall.args.every((arg, index) => arg === args[index])
+ ) {
+ return prevCall.returnValue;
+ }
+
+ prevCall = {
+ args,
+ this: this,
+ returnValue: func.apply(this, args),
+ };
+
+ return prevCall.returnValue;
+ } as T;
+
+ return memoizedFunction;
+}
+
+export { memoizeLast };
diff --git a/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts b/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
new file mode 100644
index 0000000000000..8495da72d2513
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
@@ -0,0 +1,206 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { ApolloError, ApolloQueryResult } from 'apollo-client';
+import { DocumentNode } from 'graphql';
+import { Action as ReduxAction } from 'redux';
+import { Epic } from 'redux-observable';
+import { from, merge, Observable, pipe } from 'rxjs';
+import { catchError, filter, map, startWith, switchMap, withLatestFrom } from 'rxjs/operators';
+import { Action, ActionCreator, actionCreatorFactory, Failure, Success } from 'typescript-fsa';
+import { reducerWithInitialState } from 'typescript-fsa-reducers';
+
+import { createSelector } from 'reselect';
+import { InfraApolloClient } from '../../lib/lib';
+import {
+ isFailureLoadingResult,
+ isIdleLoadingProgress,
+ isRunningLoadingProgress,
+ isSuccessLoadingResult,
+ isUninitializedLoadingResult,
+ LoadingPolicy,
+ LoadingProgress,
+ LoadingResult,
+} from '../loading_state';
+
+export interface GraphqlState {
+ current: LoadingProgress>;
+ last: LoadingResult>;
+ data: State | undefined;
+}
+
+interface OperationInfo {
+ operationKey: string;
+ variables: Variables;
+}
+
+type ResolveDonePayload = Success>;
+type ResolveFailedPayload = Failure;
+
+interface OperationActionCreators {
+ resolve: ActionCreator;
+ resolveStarted: ActionCreator;
+ resolveDone: ActionCreator>;
+ resolveFailed: ActionCreator>;
+}
+
+export const createGraphqlInitialState = (initialData?: State): GraphqlState => ({
+ current: {
+ progress: 'idle',
+ },
+ last: {
+ result: 'uninitialized',
+ },
+ data: initialData,
+});
+
+export const createGraphqlOperationActionCreators = (
+ stateKey: string,
+ operationKey: string
+): OperationActionCreators => {
+ const actionCreator = actionCreatorFactory(`kibana/infra/graphql/${stateKey}/${operationKey}`);
+
+ const resolve = actionCreator('RESOLVE');
+ const resolveEffect = actionCreator.async>('RESOLVE');
+
+ return {
+ resolve,
+ resolveStarted: resolveEffect.started,
+ resolveDone: resolveEffect.done,
+ resolveFailed: resolveEffect.failed,
+ };
+};
+
+export const createGraphqlOperationReducer = (
+ operationKey: string,
+ initialState: GraphqlState,
+ actionCreators: OperationActionCreators,
+ reduceSuccess: (
+ state: State | undefined,
+ action: Action>
+ ) => State | undefined = state => state
+) =>
+ reducerWithInitialState(initialState)
+ .caseWithAction(actionCreators.resolveStarted, (state, action) => ({
+ ...state,
+ current: {
+ progress: 'running',
+ time: Date.now(),
+ parameters: {
+ operationKey,
+ variables: action.payload,
+ },
+ },
+ }))
+ .caseWithAction(actionCreators.resolveDone, (state, action) => ({
+ ...state,
+ current: {
+ progress: 'idle',
+ },
+ last: {
+ result: 'success',
+ parameters: {
+ operationKey,
+ variables: action.payload.params,
+ },
+ time: Date.now(),
+ isExhausted: false,
+ },
+ data: reduceSuccess(state.data, action),
+ }))
+ .caseWithAction(actionCreators.resolveFailed, (state, action) => ({
+ ...state,
+ current: {
+ progress: 'idle',
+ },
+ last: {
+ result: 'failure',
+ reason: `${action.payload}`,
+ time: Date.now(),
+ parameters: {
+ operationKey,
+ variables: action.payload.params,
+ },
+ },
+ }))
+ .build();
+
+export const createGraphqlQueryEpic = (
+ graphqlQuery: DocumentNode,
+ actionCreators: OperationActionCreators
+): Epic<
+ ReduxAction,
+ ReduxAction,
+ any,
+ {
+ apolloClient$: Observable;
+ }
+> => (action$, state$, { apolloClient$ }) =>
+ action$.pipe(
+ filter(actionCreators.resolve.match),
+ withLatestFrom(apolloClient$),
+ switchMap(([{ payload: variables }, apolloClient]) =>
+ from(
+ apolloClient.query({
+ query: graphqlQuery,
+ variables,
+ fetchPolicy: 'no-cache',
+ })
+ ).pipe(
+ map(result => actionCreators.resolveDone({ params: variables, result })),
+ catchError(error => [actionCreators.resolveFailed({ params: variables, error })]),
+ startWith(actionCreators.resolveStarted(variables))
+ )
+ )
+ );
+
+export const createGraphqlStateSelectors = (
+ selectState: (parentState: any) => GraphqlState = parentState => parentState
+) => {
+ const selectData = createSelector(selectState, state => state.data);
+
+ const selectLoadingProgress = createSelector(selectState, state => state.current);
+ const selectLoadingProgressOperationInfo = createSelector(
+ selectLoadingProgress,
+ progress => (isRunningLoadingProgress(progress) ? progress.parameters : null)
+ );
+ const selectIsLoading = createSelector(selectLoadingProgress, isRunningLoadingProgress);
+ const selectIsIdle = createSelector(selectLoadingProgress, isIdleLoadingProgress);
+
+ const selectLoadingResult = createSelector(selectState, state => state.last);
+ const selectLoadingResultOperationInfo = createSelector(
+ selectLoadingResult,
+ result => (!isUninitializedLoadingResult(result) ? result.parameters : null)
+ );
+ const selectIsUninitialized = createSelector(selectLoadingResult, isUninitializedLoadingResult);
+ const selectIsSuccess = createSelector(selectLoadingResult, isSuccessLoadingResult);
+ const selectIsFailure = createSelector(selectLoadingResult, isFailureLoadingResult);
+
+ const selectLoadingState = createSelector(
+ selectLoadingProgress,
+ selectLoadingResult,
+ (loadingProgress, loadingResult) => ({
+ current: loadingProgress,
+ last: loadingResult,
+ policy: {
+ policy: 'manual',
+ } as LoadingPolicy,
+ })
+ );
+
+ return {
+ selectData,
+ selectIsFailure,
+ selectIsIdle,
+ selectIsLoading,
+ selectIsSuccess,
+ selectIsUninitialized,
+ selectLoadingProgress,
+ selectLoadingProgressOperationInfo,
+ selectLoadingResult,
+ selectLoadingState,
+ };
+};
diff --git a/x-pack/plugins/infra/public/utils/typed_react.ts b/x-pack/plugins/infra/public/utils/typed_react.ts
new file mode 100644
index 0000000000000..09c665a5a054b
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/typed_react.ts
@@ -0,0 +1,123 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import omit from 'lodash/fp/omit';
+import React from 'react';
+import { InferableComponentEnhancerWithProps } from 'react-redux';
+
+export type ChildFunctionRendererProps = {
+ children: (params: RenderArgs) => React.ReactElement | null;
+} & RenderArgs;
+
+export const asChildFunctionRenderer = (
+ hoc: InferableComponentEnhancerWithProps
+) =>
+ hoc(
+ Object.assign(
+ (props: ChildFunctionRendererProps) => props.children(omit('children', props)),
+ {
+ displayName: 'ChildFunctionRenderer',
+ }
+ )
+ );
+
+// type ComposableComponent = React.ComponentType<{
+// children: (props: ChildProps) => React.ReactElement | null;
+// }>;
+
+// type PropsOf = Component extends React.ComponentType<{
+// children: (props: infer Props) => any;
+// }>
+// ? Props
+// : never;
+
+// export const Compose2 = <
+// C1 extends ComposableComponent,
+// C2 extends ComposableComponent
+// >(props: {
+// children: (args: [PropsOf, PropsOf]) => React.ReactElement | null;
+// components: [C1, C2];
+// }) => {
+// const { composedElement, composedRender } = props.components
+// .slice()
+// .reverse()
+// .reduce<{ composedElement: React.ReactElement; composedRender: any }>((acc, component) => {
+// const renderNext = (value: any): any => acc.composedElement
+// return {
+// composedElement: React.createElement(component, { children: renderNext }),
+// composedRender: null,
+// };
+// }, {});
+
+// return composedElement;
+// };
+// React.createElement(props.components[0], {
+// children: (p1: PropsOf): any =>
+// React.createElement(props.components[1], {
+// children: (p2: PropsOf): any =>
+// React.createElement(props.components[2], {
+// children: (p3: PropsOf): any => props.children([p1, p2]),
+// }),
+// }),
+// });
+// React.createElement(props.components[0], {
+// children: (p1: PropsOf): any =>
+// React.createElement(props.components[1], {
+// children: (p2: PropsOf): any => props.children([p1, p2]),
+// }),
+// });
+// React.cloneElement(props.elements[0], undefined, (p1: P1) =>
+// React.cloneElement(props.elements[1], undefined, (p2: P2) => props.children([p1, p2]))
+// );
+
+// type ComposableElement = React.ReactElement<{
+// children: (props: Props) => React.ReactElement | null;
+// }>;
+
+// type ComposableComponent =
+// | ComposableElement
+// | (({ results, render }: { results: any, render: any }) => ComposableElement);
+
+// type ComposableComponents = Array>;
+
+// type PropsOf = Component extends ComposableComponent ? Props : never;
+
+// type ComposedPropsOf = {
+// [Index in keyof Components]: PropsOf
+// };
+
+// interface ComposeComponentsProps {
+// children: (props: ComposedPropsOf) => React.ReactElement | null;
+// components: Components;
+// }
+
+// export const ComposeComponents = (
+// props: ComposeComponentsProps
+// ) => null;
+
+// function renderRecursively>(
+// render: (props: ComposedProps) => React.ReactElement | null,
+// composables: ComposableComponents,
+// accumulatedProps: ComposedProps = [] as any
+// ) {
+// const [composable, ...otherComposables] = composables;
+// // Once components is exhausted, we can render out the results array.
+// if (!composable) {
+// return render(accumulatedProps);
+// }
+
+// // Continue recursion for remaining items.
+// // results.concat([value]) ensures [...results, value] instead of [...results, ...value]
+// const renderNext = (nextProps: ComposedProps[number]) =>
+// renderRecursively(render, otherComposables, [...accumulatedProps, nextProps]);
+
+// // Each props.components entry is either an element or function [element factory]
+// return typeof composable === 'function'
+// ? // When it is a function, produce an element by invoking it with "render component values".
+// composable({ results, render: nextRender })
+// : // When it is an element, enhance the element's props with the render prop.
+// cloneElement(remaining[0], { children: nextRender });
+// }
diff --git a/x-pack/plugins/infra/public/utils/typed_redux.ts b/x-pack/plugins/infra/public/utils/typed_redux.ts
index 6a9bc1fd5d02a..391c580902176 100644
--- a/x-pack/plugins/infra/public/utils/typed_redux.ts
+++ b/x-pack/plugins/infra/public/utils/typed_redux.ts
@@ -56,11 +56,9 @@ interface ActionCreators {
[key: string]: (arg: any) => any;
}
-type PlainActionCreator = WrappedActionCreator extends (
- payload: infer A
-) => infer R
- ? (payload: A) => R
- : never;
+type PlainActionCreator = WrappedActionCreator extends () => infer R
+ ? () => R
+ : WrappedActionCreator extends (payload: infer A) => infer R ? (payload: A) => R : never;
export const bindPlainActionCreators = (
actionCreators: WrappedActionCreators
diff --git a/x-pack/plugins/infra/scripts/combined_schema.ts b/x-pack/plugins/infra/scripts/combined_schema.ts
index d3cf58a299ed6..219a0c7f9bdf7 100644
--- a/x-pack/plugins/infra/scripts/combined_schema.ts
+++ b/x-pack/plugins/infra/scripts/combined_schema.ts
@@ -6,10 +6,9 @@
import { buildSchemaFromTypeDefinitions } from 'graphql-tools';
-import { schemas as clientSchemas } from '../public/graphql';
import { schemas as serverSchemas } from '../server/graphql';
-export const schemas = [...serverSchemas, ...clientSchemas];
+export const schemas = [...serverSchemas];
// this default export is used to feed the combined types to the gql-gen tool
// which generates the corresponding typescript types.
diff --git a/x-pack/plugins/infra/scripts/generate_types_from_graphql.js b/x-pack/plugins/infra/scripts/generate_types_from_graphql.js
index e3015b2d1ffc0..8cffac2beef3b 100644
--- a/x-pack/plugins/infra/scripts/generate_types_from_graphql.js
+++ b/x-pack/plugins/infra/scripts/generate_types_from_graphql.js
@@ -8,20 +8,35 @@ const { join, resolve } = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies
const { generate } = require('graphql-code-generator');
-const GRAPHQL_GLOB = join('public', 'containers', '**', '*.ts{,x}');
+const GRAPHQL_GLOBS = [
+ join('public', 'containers', '**', '*.gql_query.ts{,x}'),
+ join('common', 'graphql', '**', '*.gql_query.ts{,x}')
+];
const CONFIG_PATH = resolve(__dirname, 'gql_gen.json');
-const OUTPUT_PATH = resolve('common', 'graphql', 'types.ts');
+const OUTPUT_INTROSPECTION_PATH = resolve('common', 'graphql', 'introspection.json');
+const OUTPUT_TYPES_PATH = resolve('common', 'graphql', 'types.ts');
const SCHEMA_PATH = resolve(__dirname, 'combined_schema.ts');
async function main() {
await generate(
{
- args: [GRAPHQL_GLOB],
+ args: GRAPHQL_GLOBS,
config: CONFIG_PATH,
- out: OUTPUT_PATH,
+ out: OUTPUT_INTROSPECTION_PATH,
overwrite: true,
require: ['ts-node/register'],
schema: SCHEMA_PATH,
+ template: 'graphql-codegen-introspection-template',
+ },
+ true
+ );
+ await generate(
+ {
+ args: GRAPHQL_GLOBS,
+ config: CONFIG_PATH,
+ out: OUTPUT_TYPES_PATH,
+ overwrite: true,
+ schema: OUTPUT_INTROSPECTION_PATH,
template: 'graphql-codegen-typescript-template',
},
true
diff --git a/x-pack/plugins/infra/server/graphql/fields/schema.gql.ts b/x-pack/plugins/infra/server/graphql/fields/schema.gql.ts
index aa8816d97f0d3..e77a70492fa67 100644
--- a/x-pack/plugins/infra/server/graphql/fields/schema.gql.ts
+++ b/x-pack/plugins/infra/server/graphql/fields/schema.gql.ts
@@ -7,7 +7,7 @@
import gql from 'graphql-tag';
export const fieldsSchema = gql`
- interface InfraField {
+ type InfraField {
name: String
type: String
searchable: Boolean
diff --git a/x-pack/plugins/infra/server/graphql/index.ts b/x-pack/plugins/infra/server/graphql/index.ts
index d38dd6c235695..4fbe5c8e8a371 100644
--- a/x-pack/plugins/infra/server/graphql/index.ts
+++ b/x-pack/plugins/infra/server/graphql/index.ts
@@ -5,9 +5,17 @@
*/
import { rootSchema } from '../../common/graphql/root/schema.gql';
+import { sharedSchema } from '../../common/graphql/shared/schema.gql';
import { fieldsSchema } from './fields/schema.gql';
import { logEntriesSchema } from './log_entries/schema.gql';
import { nodesSchema } from './nodes/schema.gql';
import { sourcesSchema } from './sources/schema.gql';
-export const schemas = [rootSchema, fieldsSchema, logEntriesSchema, nodesSchema, sourcesSchema];
+export const schemas = [
+ rootSchema,
+ sharedSchema,
+ fieldsSchema,
+ logEntriesSchema,
+ nodesSchema,
+ sourcesSchema,
+];
diff --git a/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts b/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts
index 94305067b3aa5..d649b174c68ce 100644
--- a/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts
+++ b/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts
@@ -42,19 +42,32 @@ export const createLogEntriesResolvers = (libs: {
} => ({
InfraSource: {
async logEntriesAround(source, args, { req }) {
- const entries = await libs.logEntries.getLogEntriesAround(
+ const countBefore = args.countBefore || 0;
+ const countAfter = args.countAfter || 0;
+
+ const { entriesBefore, entriesAfter } = await libs.logEntries.getLogEntriesAround(
req,
source.id,
args.key,
- args.countBefore || 0,
- args.countAfter || 0,
+ countBefore + 1,
+ countAfter + 1,
args.filterQuery || undefined,
args.highlightQuery || undefined
);
+ const hasMoreBefore = entriesBefore.length > countBefore;
+ const hasMoreAfter = entriesAfter.length > countAfter;
+
+ const entries = [
+ ...(hasMoreBefore ? entriesBefore.slice(1) : entriesBefore),
+ ...(hasMoreAfter ? entriesAfter.slice(0, -1) : entriesAfter),
+ ];
+
return {
start: entries.length > 0 ? entries[0].key : null,
end: entries.length > 0 ? entries[entries.length - 1].key : null,
+ hasMoreBefore,
+ hasMoreAfter,
filterQuery: args.filterQuery,
highlightQuery: args.highlightQuery,
entries,
@@ -73,6 +86,8 @@ export const createLogEntriesResolvers = (libs: {
return {
start: entries.length > 0 ? entries[0].key : null,
end: entries.length > 0 ? entries[entries.length - 1].key : null,
+ hasMoreBefore: true,
+ hasMoreAfter: true,
filterQuery: args.filterQuery,
highlightQuery: args.highlightQuery,
entries,
diff --git a/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts b/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts
index d7aaab7f74901..4fd5856627d53 100644
--- a/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts
+++ b/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts
@@ -7,19 +7,6 @@
import gql from 'graphql-tag';
export const logEntriesSchema = gql`
- "A representation of the log entry's position in the event stream"
- type InfraTimeKey {
- "The timestamp of the event that the log entry corresponds to"
- time: Float!
- "The tiebreaker that disambiguates events with the same timestamp"
- tiebreaker: Float!
- }
-
- input InfraTimeKeyInput {
- time: Float!
- tiebreaker: Float!
- }
-
"A segment of the log entry message that was derived from a field"
type InfraLogMessageFieldSegment {
"The field the segment was derived from"
@@ -57,6 +44,10 @@ export const logEntriesSchema = gql`
start: InfraTimeKey
"The key corresponding to the end of the interval covered by the entries"
end: InfraTimeKey
+ "Whether there are more log entries available before the start"
+ hasMoreBefore: Boolean!
+ "Whether there are more log entries available after the end"
+ hasMoreAfter: Boolean!
"The query the log entries were filtered by"
filterQuery: String
"The query the log entries were highlighted with"
diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
index 2a42222b30de0..6aa1b37ccaa64 100644
--- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
@@ -7,6 +7,8 @@
import { GraphQLResolveInfo, GraphQLSchema } from 'graphql';
import { IRouteAdditionalConfigurationOptions, IStrictReply } from 'hapi';
+export * from '../../../../common/graphql/typed_resolvers';
+
export const internalInfraFrameworkRequest = Symbol('internalInfraFrameworkRequest');
export interface InfraBackendFrameworkAdapter {
@@ -130,82 +132,3 @@ export interface InfraFieldDetails {
export interface InfraFieldDef {
[type: string]: InfraFieldDetails;
}
-
-/**
- * GraphQL types
- */
-
-type BasicResolver = (
- parent: any,
- args: Args,
- context: any,
- info: GraphQLResolveInfo
-) => Promise | Result;
-
-type InfraResolverResult =
- | Promise
- | Promise<{ [P in keyof R]: () => Promise }>
- | { [P in keyof R]: () => Promise }
- | { [P in keyof R]: () => R[P] }
- | R;
-
-export type InfraResolvedResult = Resolver extends InfraResolver<
- infer Result,
- any,
- any,
- any
->
- ? Result
- : never;
-
-export type SubsetResolverWithFields = R extends BasicResolver<
- Array,
- infer ArgsInArray
->
- ? BasicResolver<
- Array>>,
- ArgsInArray
- >
- : R extends BasicResolver
- ? BasicResolver>, Args>
- : never;
-
-export type SubsetResolverWithoutFields = R extends BasicResolver<
- Array,
- infer ArgsInArray
->
- ? BasicResolver<
- Array>>,
- ArgsInArray
- >
- : R extends BasicResolver
- ? BasicResolver>, Args>
- : never;
-
-export type InfraResolver = (
- parent: Parent,
- args: Args,
- context: Context,
- info: GraphQLResolveInfo
-) => InfraResolverResult;
-
-export type InfraResolverOf = Resolver extends BasicResolver<
- infer Result,
- infer Args
->
- ? InfraResolver
- : never;
-
-export type InfraResolverWithFields<
- Resolver,
- Parent,
- Context,
- IncludedFields extends string
-> = InfraResolverOf, Parent, Context>;
-
-export type InfraResolverWithoutFields<
- Resolver,
- Parent,
- Context,
- ExcludedFields extends string
-> = InfraResolverOf, Parent, Context>;
diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts
index 8b84e8f28cffd..b003981d33b1e 100644
--- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts
+++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts
@@ -25,9 +25,12 @@ export class InfraLogEntriesDomain {
maxCountAfter: number,
filterQuery?: string,
highlightQuery?: string
- ): Promise {
+ ): Promise<{ entriesBefore: InfraLogEntry[]; entriesAfter: InfraLogEntry[] }> {
if (maxCountBefore <= 0 && maxCountAfter <= 0) {
- return [];
+ return {
+ entriesBefore: [],
+ entriesAfter: [],
+ };
}
const sourceConfiguration = await this.libs.sources.getConfiguration(sourceId);
@@ -62,11 +65,12 @@ export class InfraLogEntriesDomain {
highlightQuery
);
- const entries = [...(maxCountBefore > 0 ? documentsBefore : []), ...documentsAfter].map(
- convertLogDocumentToEntry(sourceId, formattingRules.format)
- );
-
- return entries;
+ return {
+ entriesBefore: (maxCountBefore > 0 ? documentsBefore : []).map(
+ convertLogDocumentToEntry(sourceId, formattingRules.format)
+ ),
+ entriesAfter: documentsAfter.map(convertLogDocumentToEntry(sourceId, formattingRules.format)),
+ };
}
public async getLogEntriesBetween(
diff --git a/x-pack/plugins/infra/types/redux_observable.d.ts b/x-pack/plugins/infra/types/redux_observable.d.ts
index 618c8246efbf7..6813c4bf6a054 100644
--- a/x-pack/plugins/infra/types/redux_observable.d.ts
+++ b/x-pack/plugins/infra/types/redux_observable.d.ts
@@ -17,10 +17,7 @@ declare module 'redux-observable' {
S,
D1,
D2
- >(
- epic1: Epic,
- epic2: Epic
- ): Epic;
+ >(epic1: Epic, epic2: Epic): Epic;
function combineEpics<
T1 extends Action,
T2 extends Action,
@@ -80,10 +77,9 @@ declare module 'redux-observable' {
epic3: Epic,
epic4: Epic,
epic5: Epic
- ): Epic<
- T1 | T2 | T3 | T4 | T5,
- O1 | O2 | O3 | O4 | O5,
- S,
- D1 & D2 & D3 & D4 & D5
- >;
+ ): Epic;
+
+ type EpicWithState = E extends Epic
+ ? Epic
+ : E;
}
diff --git a/x-pack/yarn.lock b/x-pack/yarn.lock
index 3640ccf87e21e..d9328d5b777ef 100644
--- a/x-pack/yarn.lock
+++ b/x-pack/yarn.lock
@@ -323,6 +323,12 @@
dependencies:
csstype "^2.2.0"
+"@types/reduce-reducers@^0.1.3":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@types/reduce-reducers/-/reduce-reducers-0.1.3.tgz#69f252207622ced7e063c7526ad46ec60b69f0c0"
+ dependencies:
+ redux "^3.6.0"
+
"@types/retry@*", "@types/retry@^0.10.2":
version "0.10.2"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.10.2.tgz#bd1740c4ad51966609b058803ee6874577848b37"
@@ -3721,6 +3727,10 @@ graphql-codegen-core@0.10.1:
graphql-tools "3.0.4"
winston "2.4.3"
+graphql-codegen-introspection-template@^0.10.5:
+ version "0.10.5"
+ resolved "https://registry.yarnpkg.com/graphql-codegen-introspection-template/-/graphql-codegen-introspection-template-0.10.5.tgz#c8c0f647a9771c4e3c6ffbe26aa8da15af9af661"
+
graphql-codegen-typescript-template@^0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/graphql-codegen-typescript-template/-/graphql-codegen-typescript-template-0.10.1.tgz#bb631d2ebfcd8f15117ca642a9988bd767183e02"
@@ -5289,7 +5299,7 @@ lodash-es@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
-lodash-es@^4.17.5:
+lodash-es@^4.17.5, lodash-es@^4.2.1:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"
@@ -5530,7 +5540,7 @@ lodash@3.10.1, lodash@^3.10.0, lodash@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
-lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.5, lodash@^4.2.0, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@~4.17.10:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
@@ -7386,6 +7396,10 @@ reduce-reducers@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.1.2.tgz#fa1b4718bc5292a71ddd1e5d839c9bea9770f14b"
+reduce-reducers@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.4.3.tgz#8e052618801cd8fc2714b4915adaa8937eb6d66c"
+
redux-actions@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.2.1.tgz#d64186b25649a13c05478547d7cd7537b892410d"
@@ -7414,6 +7428,15 @@ redux@4.0.0, redux@^4.0.0:
loose-envify "^1.1.0"
symbol-observable "^1.2.0"
+redux@^3.6.0:
+ version "3.7.2"
+ resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b"
+ dependencies:
+ lodash "^4.2.1"
+ lodash-es "^4.2.1"
+ loose-envify "^1.1.0"
+ symbol-observable "^1.0.3"
+
regenerate@^1.2.1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
@@ -8480,7 +8503,7 @@ swap-case@^1.1.0:
lower-case "^1.1.1"
upper-case "^1.1.1"
-symbol-observable@^1.0.2, symbol-observable@^1.2.0:
+symbol-observable@^1.0.2, symbol-observable@^1.0.3, symbol-observable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
diff --git a/yarn.lock b/yarn.lock
index 403280da7edb7..d46e5428af58a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11653,6 +11653,10 @@ reduce-reducers@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.1.2.tgz#fa1b4718bc5292a71ddd1e5d839c9bea9770f14b"
+reduce-reducers@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.4.3.tgz#8e052618801cd8fc2714b4915adaa8937eb6d66c"
+
redux-actions@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/redux-actions/-/redux-actions-2.2.1.tgz#d64186b25649a13c05478547d7cd7537b892410d"
From b7682067eb448fea53d4aca2cf61c71bcbfbfdd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Mon, 13 Aug 2018 19:03:51 +0200
Subject: [PATCH 4/6] Fix linter errors
---
.../components/waffle/lib/size_of_squares.ts | 12 ++++++------
.../logging_legacy/state/entries/epics.ts | 4 +---
.../containers/logging_legacy/state/selectors.ts | 2 +-
.../infra/public/lib/compose/kibana_compose.ts | 2 --
.../infra/public/utils/log_entry/log_entry.ts | 7 +------
.../utils/remote_state/remote_graphql_state.ts | 3 ++-
.../lib/adapters/framework/adapter_types.ts | 2 +-
.../adapters/nodes/extract_paths_and_metrics.ts | 14 ++++++++------
.../adapters/nodes/lib/extract_group_paths.ts | 16 +++++++++-------
9 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts b/x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts
index bcdc9e49d82d4..2c443d12cd02f 100644
--- a/x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts
+++ b/x-pack/plugins/infra/public/components/waffle/lib/size_of_squares.ts
@@ -18,18 +18,18 @@ export function sizeOfSquares(
const scale = SCALE_FACTOR / levelFactor;
const x = width * scale;
const y = height * scale;
- const possibleX = Math.ceil(Math.sqrt(totalItems * x / y));
+ const possibleX = Math.ceil(Math.sqrt((totalItems * x) / y));
let newX;
let newY;
- if (Math.floor(possibleX * y / x) * possibleX < totalItems) {
- newX = y / Math.ceil(possibleX * y / x);
+ if (Math.floor((possibleX * y) / x) * possibleX < totalItems) {
+ newX = y / Math.ceil((possibleX * y) / x);
} else {
newX = x / possibleX;
}
- const possibleY = Math.ceil(Math.sqrt(totalItems * y / x));
- if (Math.floor(possibleY * x / y) * possibleY < totalItems) {
+ const possibleY = Math.ceil(Math.sqrt((totalItems * y) / x));
+ if (Math.floor((possibleY * x) / y) * possibleY < totalItems) {
// does not fit
- newY = x / Math.ceil(x * possibleY / y);
+ newY = x / Math.ceil((x * possibleY) / y);
} else {
newY = y / possibleY;
}
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
index 691f140546add..5f971e78ea4bd 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/entries/epics.ts
@@ -4,14 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import pick from 'lodash/fp/pick';
import { Action } from 'redux';
import { combineEpics, Epic, EpicWithState } from 'redux-observable';
-import { /*interval,*/ merge, Observable } from 'rxjs';
+import { /*interval,*/ merge } from 'rxjs';
import { exhaustMap, filter, map, withLatestFrom } from 'rxjs/operators';
import { pickTimeKey, TimeKey, timeKeyIsBetween } from '../../../../../common/time';
-import { InfraApolloClient } from '../../../../lib/lib';
import { targetActions } from '../target';
import {
loadEntries,
diff --git a/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts b/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
index 8043fa86fa87d..941131233200b 100644
--- a/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
+++ b/x-pack/plugins/infra/public/containers/logging_legacy/state/selectors.ts
@@ -6,12 +6,12 @@
import { createSelector } from 'reselect';
-import { getLogEntryKey } from '../../../utils/log_entry';
import {
getSearchResultIndexAfterTime,
getSearchResultIndexBeforeTime,
getSearchResultKey,
} from '../../../../common/log_search_result';
+import { getLogEntryKey } from '../../../utils/log_entry';
import { globalizeSelectors } from '../../../utils/typed_redux';
import { configurationSelectors as localConfigurationSelectors } from './configuration';
import { entriesSelectors as localEntriesSelectors } from './entries';
diff --git a/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts b/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
index 7693a8bc9b34e..732d417fdebcd 100644
--- a/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
+++ b/x-pack/plugins/infra/public/lib/compose/kibana_compose.ts
@@ -25,8 +25,6 @@ import ApolloClient from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { withClientState } from 'apollo-link-state';
-import { printSchema } from 'graphql';
-import { buildSchemaFromTypeDefinitions } from 'graphql-tools';
export function compose(): InfraFrontendLibs {
const cache = new InMemoryCache({
diff --git a/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts b/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
index 30de10c710180..b37d5e234dbf5 100644
--- a/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
+++ b/x-pack/plugins/infra/public/utils/log_entry/log_entry.ts
@@ -7,12 +7,7 @@
import { bisector } from 'd3-array';
import { LogEntries as LogEntriesQuery } from '../../../common/graphql/types';
-import {
- compareTimeKeys,
- compareToTimeKey,
- getIndexAtTimeKey,
- TimeKey,
-} from '../../../common/time';
+import { compareToTimeKey, getIndexAtTimeKey } from '../../../common/time';
export type LogEntry = LogEntriesQuery.Entries;
diff --git a/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts b/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
index 8495da72d2513..8af643bbcb2fb 100644
--- a/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
+++ b/x-pack/plugins/infra/public/utils/remote_state/remote_graphql_state.ts
@@ -8,7 +8,7 @@ import { ApolloError, ApolloQueryResult } from 'apollo-client';
import { DocumentNode } from 'graphql';
import { Action as ReduxAction } from 'redux';
import { Epic } from 'redux-observable';
-import { from, merge, Observable, pipe } from 'rxjs';
+import { from, Observable } from 'rxjs';
import { catchError, filter, map, startWith, switchMap, withLatestFrom } from 'rxjs/operators';
import { Action, ActionCreator, actionCreatorFactory, Failure, Success } from 'typescript-fsa';
import { reducerWithInitialState } from 'typescript-fsa-reducers';
@@ -201,6 +201,7 @@ export const createGraphqlStateSelectors = (
selectLoadingProgress,
selectLoadingProgressOperationInfo,
selectLoadingResult,
+ selectLoadingResultOperationInfo,
selectLoadingState,
};
};
diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
index 6aa1b37ccaa64..025505ceb28b6 100644
--- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { GraphQLResolveInfo, GraphQLSchema } from 'graphql';
+import { GraphQLSchema } from 'graphql';
import { IRouteAdditionalConfigurationOptions, IStrictReply } from 'hapi';
export * from '../../../../common/graphql/typed_resolvers';
diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/extract_paths_and_metrics.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/extract_paths_and_metrics.ts
index 0d0173bcb9a2e..7b5b514bbdf57 100644
--- a/x-pack/plugins/infra/server/lib/adapters/nodes/extract_paths_and_metrics.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/nodes/extract_paths_and_metrics.ts
@@ -87,13 +87,15 @@ function parseFieldNodes(
): InfraPathsAndMetricOptions {
if (isFieldNode(node) && node.selectionSet) {
const { selections }: SelectionSetNode = node.selectionSet;
- selections.forEach((selection: SelectionNode): void => {
- if (isMetricSelection(selection) && selection.arguments) {
- const metrics = extractMetricsArgument(selection);
- ctx.metrics = metrics || [];
+ selections.forEach(
+ (selection: SelectionNode): void => {
+ if (isMetricSelection(selection) && selection.arguments) {
+ const metrics = extractMetricsArgument(selection);
+ ctx.metrics = metrics || [];
+ }
+ parseFieldNodes(ctx, selection);
}
- parseFieldNodes(ctx, selection);
- });
+ );
if (hasPathArguments(node)) {
const paths = extractPathArgument(node);
ctx.path = paths || [];
diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts
index e91b72c80822d..d42cac8475614 100644
--- a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts
@@ -25,13 +25,15 @@ export function extractGroupPaths(
const key: string = String(bucket.key || index);
if (secondGroup) {
return acc.concat(
- bucket.path_1.buckets.map((b: InfraBucket): InfraNode => {
- const nodePath = [{ value: bucket.key }, { value: b.key }].concat(nodeItem.path);
- return {
- ...nodeItem,
- path: nodePath,
- };
- })
+ bucket.path_1.buckets.map(
+ (b: InfraBucket): InfraNode => {
+ const nodePath = [{ value: bucket.key }, { value: b.key }].concat(nodeItem.path);
+ return {
+ ...nodeItem,
+ path: nodePath,
+ };
+ }
+ )
);
}
const path = [{ value: key }].concat(nodeItem.path);
From ad4f34ffa6d9a20fb8398c96119c3e519db6625f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Wed, 15 Aug 2018 22:49:15 +0200
Subject: [PATCH 5/6] Fix query filename after glob pattern change in script
---
x-pack/plugins/infra/common/graphql/types.ts | 42 +++++++++++++++++++
.../map/{query.ts => map.gql_query.ts} | 2 +
.../infra/public/containers/map/with_map.ts | 5 ++-
3 files changed, 47 insertions(+), 2 deletions(-)
rename x-pack/plugins/infra/public/containers/map/{query.ts => map.gql_query.ts} (99%)
diff --git a/x-pack/plugins/infra/common/graphql/types.ts b/x-pack/plugins/infra/common/graphql/types.ts
index 5f32a8bfb0690..8171893426438 100644
--- a/x-pack/plugins/infra/common/graphql/types.ts
+++ b/x-pack/plugins/infra/common/graphql/types.ts
@@ -515,6 +515,48 @@ export namespace LogEntries {
constant: string;
};
}
+export namespace MapQuery {
+ export type Variables = {
+ id: string;
+ timerange: InfraTimerangeInput;
+ filters?: InfraFilterInput[] | null;
+ metrics?: InfraMetricInput[] | null;
+ path?: InfraPathInput[] | null;
+ };
+
+ export type Query = {
+ __typename?: 'Query';
+ source: Source;
+ };
+
+ export type Source = {
+ __typename?: 'InfraSource';
+ id: string;
+ map?: Map | null;
+ };
+
+ export type Map = {
+ __typename?: 'InfraResponse';
+ nodes: Nodes[];
+ };
+
+ export type Nodes = {
+ __typename?: 'InfraNode';
+ path: Path[];
+ metrics: Metrics[];
+ };
+
+ export type Path = {
+ __typename?: 'InfraNodePath';
+ value: string;
+ };
+
+ export type Metrics = {
+ __typename?: 'InfraNodeMetric';
+ name: string;
+ value: number;
+ };
+}
export namespace InfraTimeKeyFields {
export type Fragment = {
diff --git a/x-pack/plugins/infra/public/containers/map/query.ts b/x-pack/plugins/infra/public/containers/map/map.gql_query.ts
similarity index 99%
rename from x-pack/plugins/infra/public/containers/map/query.ts
rename to x-pack/plugins/infra/public/containers/map/map.gql_query.ts
index edea088297c94..5ae90ab4dd161 100644
--- a/x-pack/plugins/infra/public/containers/map/query.ts
+++ b/x-pack/plugins/infra/public/containers/map/map.gql_query.ts
@@ -3,7 +3,9 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
+
import gql from 'graphql-tag';
+
export const mapQuery = gql`
query MapQuery(
$id: ID!
diff --git a/x-pack/plugins/infra/public/containers/map/with_map.ts b/x-pack/plugins/infra/public/containers/map/with_map.ts
index 7508a25d3e859..1baec6811d029 100644
--- a/x-pack/plugins/infra/public/containers/map/with_map.ts
+++ b/x-pack/plugins/infra/public/containers/map/with_map.ts
@@ -3,12 +3,13 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import moment from 'moment';
+import * as moment from 'moment';
import { graphql } from 'react-apollo';
+
import { InfraMetricType, InfraPathType, MapQuery } from '../../../common/graphql/types';
import { InfraWaffleMapGroup } from '../../lib/lib';
+import { mapQuery } from './map.gql_query';
import { nodesToWaffleMap } from './nodes_to_wafflemap';
-import { mapQuery } from './query';
interface ChildProps {
map: InfraWaffleMapGroup[];
From 8637ecf99d6a30238eb6e872332d1c84f240ac35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20St=C3=BCrmer?=
Date: Thu, 16 Aug 2018 15:21:24 +0200
Subject: [PATCH 6/6] Fix "compator" typo
---
x-pack/plugins/infra/common/time/time_key.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/x-pack/plugins/infra/common/time/time_key.ts b/x-pack/plugins/infra/common/time/time_key.ts
index 966c4ac3c6e08..58b058ab5e953 100644
--- a/x-pack/plugins/infra/common/time/time_key.ts
+++ b/x-pack/plugins/infra/common/time/time_key.ts
@@ -57,8 +57,8 @@ export const getIndexAtTimeKey = (
keyAccessor: (value: Value) => TimeKey,
compareValues?: Comparator
) => {
- const compator = compareToTimeKey(keyAccessor, compareValues);
- const collectionBisector = bisector(compator);
+ const comparator = compareToTimeKey(keyAccessor, compareValues);
+ const collectionBisector = bisector(comparator);
return (collection: Value[], key: TimeKey): number | null => {
const index = collectionBisector.left(collection, key);
@@ -67,7 +67,7 @@ export const getIndexAtTimeKey = (
return null;
}
- if (compator(collection[index], key) !== 0) {
+ if (comparator(collection[index], key) !== 0) {
return null;
}