Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logs UI] HTTP API for log entry #53485

Merged
merged 6 commits into from
Dec 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 0 additions & 65 deletions x-pack/legacy/plugins/infra/common/graphql/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export interface InfraSource {
/** Sequences of log entries matching sets of highlighting queries within an interval */
logEntryHighlights: InfraLogEntryInterval[];

logItem: InfraLogItem;
/** A snapshot of nodes */
snapshot?: InfraSnapshotResponse | null;

Expand Down Expand Up @@ -205,24 +204,6 @@ export interface InfraLogEntryFieldColumn {
highlights: string[];
}

export interface InfraLogItem {
/** The ID of the document */
id: string;
/** The index where the document was found */
index: string;
/** Time key for the document - derived from the source configuration timestamp and tiebreaker settings */
key: InfraTimeKey;
/** An array of flattened fields and values */
fields: InfraLogItemField[];
}

export interface InfraLogItemField {
/** The flattened field name */
field: string;
/** The value for the Field as a string */
value: string;
}

export interface InfraSnapshotResponse {
/** Nodes of type host, container or pod grouped by 0, 1 or 2 terms */
nodes: InfraSnapshotNode[];
Expand Down Expand Up @@ -424,9 +405,6 @@ export interface LogEntryHighlightsInfraSourceArgs {
/** The highlighting to apply to the log entries */
highlights: InfraLogEntryHighlightInput[];
}
export interface LogItemInfraSourceArgs {
id: string;
}
export interface SnapshotInfraSourceArgs {
timerange: InfraTimerangeInput;

Expand Down Expand Up @@ -600,49 +578,6 @@ export type InfraLogMessageSegment = InfraLogMessageFieldSegment | InfraLogMessa
// Documents
// ====================================================

export namespace FlyoutItemQuery {
export type Variables = {
sourceId: string;
itemId: string;
};

export type Query = {
__typename?: 'Query';

source: Source;
};

export type Source = {
__typename?: 'InfraSource';

id: string;

logItem: LogItem;
};

export type LogItem = {
__typename?: 'InfraLogItem';

id: string;

index: string;

key: Key;

fields: Fields[];
};

export type Key = InfraTimeKeyFields.Fragment;

export type Fields = {
__typename?: 'InfraLogItemField';

field: string;

value: string;
};
}

export namespace LogEntryHighlightsQuery {
export type Variables = {
sourceId?: string | null;
Expand Down
12 changes: 12 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/log_entries/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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 * as rt from 'io-ts';

export const logEntriesCursorRT = rt.type({
time: rt.number,
tiebreaker: rt.number,
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

export * from './item';
export * from './summary';
export * from './summary_highlights';
32 changes: 32 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/log_entries/item.ts
Original file line number Diff line number Diff line change
@@ -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 * as rt from 'io-ts';
import { logEntriesCursorRT } from './common';

export const LOG_ENTRIES_ITEM_PATH = '/api/log_entries/item';

export const logEntriesItemRequestRT = rt.type({
sourceId: rt.string,
id: rt.string,
});

export type LogEntriesItemRequest = rt.TypeOf<typeof logEntriesItemRequestRT>;

const logEntriesItemFieldRT = rt.type({ field: rt.string, value: rt.string });
const logEntriesItemRT = rt.type({
id: rt.string,
index: rt.string,
fields: rt.array(logEntriesItemFieldRT),
key: logEntriesCursorRT,
});
export const logEntriesItemResponseRT = rt.type({
data: logEntriesItemRT,
});

export type LogEntriesItemField = rt.TypeOf<typeof logEntriesItemFieldRT>;
export type LogEntriesItem = rt.TypeOf<typeof logEntriesItemRT>;
export type LogEntriesItemResponse = rt.TypeOf<typeof logEntriesItemResponseRT>;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import * as rt from 'io-ts';
import { logEntriesSummaryRequestRT, logEntriesSummaryBucketRT } from './summary';
import { logEntriesCursorRT } from './common';

export const LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH = '/api/log_entries/summary_highlights';

Expand All @@ -23,10 +24,7 @@ export type LogEntriesSummaryHighlightsRequest = rt.TypeOf<
export const logEntriesSummaryHighlightsBucketRT = rt.intersection([
logEntriesSummaryBucketRT,
rt.type({
representativeKey: rt.type({
time: rt.number,
tiebreaker: rt.number,
}),
representativeKey: logEntriesCursorRT,
}),
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { FormattedMessage } from '@kbn/i18n/react';
import React, { useMemo } from 'react';
import url from 'url';
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
import { InfraLogItem } from '../../../graphql/types';
import { useVisibilityState } from '../../../utils/use_visibility_state';
import { getTraceUrl } from '../../../../../apm/public/components/shared/Links/apm/ExternalLinks';
import { LogEntriesItem } from '../../../../common/http_api';

const UPTIME_FIELDS = ['container.id', 'host.ip', 'kubernetes.pod.uid'];

export const LogEntryActionsMenu: React.FunctionComponent<{
logItem: InfraLogItem;
logItem: LogEntriesItem;
}> = ({ logItem }) => {
const prependBasePath = useKibana().services.http?.basePath?.prepend;
const { hide, isVisible, show } = useVisibilityState(false);
Expand Down Expand Up @@ -89,7 +89,7 @@ export const LogEntryActionsMenu: React.FunctionComponent<{
);
};

const getUptimeLink = (logItem: InfraLogItem) => {
const getUptimeLink = (logItem: LogEntriesItem) => {
const searchExpressions = logItem.fields
.filter(({ field, value }) => value != null && UPTIME_FIELDS.includes(field))
.map(({ field, value }) => `${field}:${value}`);
Expand All @@ -104,7 +104,7 @@ const getUptimeLink = (logItem: InfraLogItem) => {
});
};

const getAPMLink = (logItem: InfraLogItem) => {
const getAPMLink = (logItem: LogEntriesItem) => {
const traceIdEntry = logItem.fields.find(
({ field, value }) => value != null && field === 'trace.id'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import React, { useCallback, useMemo } from 'react';

import euiStyled from '../../../../../../common/eui_styled_components';
import { TimeKey } from '../../../../common/time';
import { InfraLogItem, InfraLogItemField } from '../../../graphql/types';
import { InfraLoadingPanel } from '../../loading';
import { LogEntryActionsMenu } from './log_entry_actions_menu';
import { LogEntriesItem, LogEntriesItemField } from '../../../../common/http_api';

interface Props {
flyoutItem: InfraLogItem | null;
flyoutItem: LogEntriesItem | null;
setFlyoutVisibility: (visible: boolean) => void;
setFilter: (filter: string) => void;
setTarget: (timeKey: TimeKey, flyoutItemId: string) => void;
Expand All @@ -43,7 +43,7 @@ export const LogEntryFlyout = ({
setTarget,
}: Props) => {
const createFilterHandler = useCallback(
(field: InfraLogItemField) => () => {
(field: LogEntriesItemField) => () => {
const filter = `${field.field}:"${field.value}"`;
setFilter(filter);

Expand Down Expand Up @@ -80,7 +80,7 @@ export const LogEntryFlyout = ({
defaultMessage: 'Value',
}),
sortable: true,
render: (_name: string, item: InfraLogItemField) => (
render: (_name: string, item: LogEntriesItemField) => (
<span>
<EuiToolTip
content={i18n.translate('xpack.infra.logFlyout.setFilterTooltip', {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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 { fold } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { identity } from 'fp-ts/lib/function';
import { kfetch } from 'ui/kfetch';

import { throwErrors, createPlainError } from '../../../../../common/runtime_types';

import {
LOG_ENTRIES_ITEM_PATH,
LogEntriesItemRequest,
logEntriesItemRequestRT,
logEntriesItemResponseRT,
} from '../../../../../common/http_api';

export const fetchLogEntriesItem = async (requestArgs: LogEntriesItemRequest) => {
const response = await kfetch({
method: 'POST',
pathname: LOG_ENTRIES_ITEM_PATH,
body: JSON.stringify(logEntriesItemRequestRT.encode(requestArgs)),
});

return pipe(
logEntriesItemResponseRT.decode(response),
fold(throwErrors(createPlainError), identity)
);
};
27 changes: 6 additions & 21 deletions x-pack/legacy/plugins/infra/public/containers/logs/log_flyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import createContainer from 'constate';
import { isString } from 'lodash';
import React, { useContext, useEffect, useMemo, useState } from 'react';

import { FlyoutItemQuery, InfraLogItem } from '../../graphql/types';
import { useApolloClient } from '../../utils/apollo_context';
import { UrlStateContainer } from '../../utils/url_state';
import { useTrackedPromise } from '../../utils/use_tracked_promise';
import { Source } from '../source';
import { flyoutItemQuery } from './flyout_item.gql_query';
import { fetchLogEntriesItem } from './log_entries/api/fetch_log_entries_item';
import { LogEntriesItem } from '../../../common/http_api';

export enum FlyoutVisibility {
hidden = 'hidden',
Expand All @@ -30,40 +29,26 @@ export const useLogFlyout = () => {
const { sourceId } = useContext(Source.Context);
const [flyoutVisible, setFlyoutVisibility] = useState<boolean>(false);
const [flyoutId, setFlyoutId] = useState<string | null>(null);
const [flyoutItem, setFlyoutItem] = useState<InfraLogItem | null>(null);
const [flyoutItem, setFlyoutItem] = useState<LogEntriesItem | null>(null);
const [surroundingLogsId, setSurroundingLogsId] = useState<string | null>(null);

const apolloClient = useApolloClient();

const [loadFlyoutItemRequest, loadFlyoutItem] = useTrackedPromise(
{
cancelPreviousOn: 'creation',
createPromise: async () => {
if (!apolloClient) {
throw new Error('Failed to load flyout item: No apollo client available.');
}

if (!flyoutId) {
return;
}

return await apolloClient.query<FlyoutItemQuery.Query, FlyoutItemQuery.Variables>({
fetchPolicy: 'no-cache',
query: flyoutItemQuery,
variables: {
itemId: flyoutId,
sourceId,
},
});
return await fetchLogEntriesItem({ sourceId, id: flyoutId });
},
onResolve: response => {
if (response) {
const { data } = response;
setFlyoutItem((data && data.source && data.source.logItem) || null);
setFlyoutItem(data || null);
}
},
},
[apolloClient, sourceId, flyoutId]
[sourceId, flyoutId]
);

const isLoading = useMemo(() => {
Expand Down
Loading