mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] Discover links with quoted values and use default 24h as time range (#24900)
* [APM] Discover links with quoted values * Use 24h as default time range
This commit is contained in:
parent
2fb2bda157
commit
704cf6182f
8 changed files with 49 additions and 30 deletions
|
@ -19,7 +19,7 @@ exports[`DetailView should render with data 1`] = `
|
|||
"interval": "auto",
|
||||
"query": Object {
|
||||
"language": "lucene",
|
||||
"query": "context.service.name:\\"opbeans-node\\" AND error.grouping_key:c00e245c2fbebaf178fc31eeb2bb0250",
|
||||
"query": "context.service.name:\\"opbeans-node\\" AND error.grouping_key:\\"c00e245c2fbebaf178fc31eeb2bb0250\\"",
|
||||
},
|
||||
"sort": Object {
|
||||
"@timestamp": "desc",
|
||||
|
|
|
@ -18,7 +18,7 @@ import { get, capitalize, isEmpty } from 'lodash';
|
|||
import { STATUS } from '../../../../constants';
|
||||
import { StickyProperties } from '../../../shared/StickyProperties';
|
||||
import { Tab, HeaderMedium } from '../../../shared/UIComponents';
|
||||
import DiscoverButton from '../../../shared/DiscoverButton';
|
||||
import { DiscoverButton } from '../../../shared/DiscoverButton';
|
||||
import {
|
||||
PropertiesTable,
|
||||
getPropertyTabNames
|
||||
|
@ -147,7 +147,7 @@ function DetailView({ errorGroup, urlParams, location }) {
|
|||
interval: 'auto',
|
||||
query: {
|
||||
language: 'lucene',
|
||||
query: `${SERVICE_NAME}:"${serviceName}" AND ${ERROR_GROUP_ID}:${groupId}${
|
||||
query: `${SERVICE_NAME}:"${serviceName}" AND ${ERROR_GROUP_ID}:"${groupId}"${
|
||||
urlParams.kuery ? ` AND ${urlParams.kuery}` : ``
|
||||
}`
|
||||
},
|
||||
|
|
|
@ -20,9 +20,9 @@ import { KibanaLink } from 'x-pack/plugins/apm/public/utils/url';
|
|||
import { Transaction } from 'x-pack/plugins/apm/typings/Transaction';
|
||||
|
||||
function getDiscoverQuery(transactionId: string, traceId?: string) {
|
||||
let query = `${PROCESSOR_EVENT}:transaction AND ${TRANSACTION_ID}:${transactionId}`;
|
||||
let query = `${PROCESSOR_EVENT}:"transaction" AND ${TRANSACTION_ID}:"${transactionId}"`;
|
||||
if (traceId) {
|
||||
query += ` AND ${TRACE_ID}:${traceId}`;
|
||||
query += ` AND ${TRACE_ID}:"${traceId}"`;
|
||||
}
|
||||
return {
|
||||
_a: {
|
||||
|
@ -68,14 +68,13 @@ export const DiscoverTransactionLink: React.SFC<ActionMenuProps> = ({
|
|||
transaction,
|
||||
children
|
||||
}) => {
|
||||
const traceId =
|
||||
transaction.version === 'v2' ? transaction.trace.id : undefined;
|
||||
return (
|
||||
<KibanaLink
|
||||
pathname="/app/kibana"
|
||||
hash="/discover"
|
||||
query={getDiscoverQuery(
|
||||
transaction.transaction.id,
|
||||
transaction.version === 'v2' ? transaction.trace.id : undefined
|
||||
)}
|
||||
query={getDiscoverQuery(transaction.transaction.id, traceId)}
|
||||
children={children}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,11 @@ import React from 'react';
|
|||
import styled from 'styled-components';
|
||||
|
||||
// @ts-ignore
|
||||
import { SERVICE_LANGUAGE_NAME } from '../../../../../../../../common/constants';
|
||||
import {
|
||||
SERVICE_LANGUAGE_NAME,
|
||||
SPAN_HEX_ID,
|
||||
SPAN_ID
|
||||
} from '../../../../../../../../common/constants';
|
||||
import { px, unit } from '../../../../../../../style/variables';
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -30,8 +34,7 @@ import { StickySpanProperties } from './StickySpanProperties';
|
|||
|
||||
import { Transaction } from 'x-pack/plugins/apm/typings/Transaction';
|
||||
import { Span } from '../../../../../../../../typings/Span';
|
||||
// @ts-ignore
|
||||
import DiscoverButton from '../../../../../../shared/DiscoverButton';
|
||||
import { DiscoverButton } from '../../../../../../shared/DiscoverButton';
|
||||
import { FlyoutTopLevelProperties } from '../FlyoutTopLevelProperties';
|
||||
|
||||
const StackTraceContainer = styled.div`
|
||||
|
@ -46,8 +49,8 @@ function getDiscoverQuery(span: Span) {
|
|||
language: 'lucene',
|
||||
query:
|
||||
span.version === 'v2'
|
||||
? `span.hex_id:${span.span.hex_id}`
|
||||
: `span.id:${span.span.id}`
|
||||
? `${SPAN_HEX_ID}:"${span.span.hex_id}"`
|
||||
: `${SPAN_ID}:"${span.span.id}"`
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,11 +4,18 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { KibanaLink } from '../../utils/url';
|
||||
// @ts-ignore
|
||||
import { EuiButtonEmpty } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { StringMap } from 'x-pack/plugins/apm/typings/common';
|
||||
import { KibanaLink } from '../../utils/url';
|
||||
|
||||
function DiscoverButton({ query, children, ...rest }) {
|
||||
interface Props {
|
||||
query: StringMap;
|
||||
children: any;
|
||||
}
|
||||
|
||||
export function DiscoverButton({ query, children, ...rest }: Props) {
|
||||
return (
|
||||
<KibanaLink
|
||||
pathname={'/app/kibana'}
|
||||
|
@ -22,5 +29,3 @@ function DiscoverButton({ query, children, ...rest }) {
|
|||
</KibanaLink>
|
||||
);
|
||||
}
|
||||
|
||||
export default DiscoverButton;
|
|
@ -13,7 +13,7 @@ exports[`RelativeLinkComponent should render correct markup 1`] = `
|
|||
exports[`UnconnectedKibanaLink should render correct markup 1`] = `
|
||||
<a
|
||||
className="euiLink euiLink--primary"
|
||||
href="myBasePath/app/kibana#/discover?_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))&_g="
|
||||
href="myBasePath/app/kibana#/discover?_a=(interval:auto,query:(language:lucene,query:'context.service.name:\\"myServiceName\\" AND error.grouping_key:\\"myGroupId\\"'),sort:('@timestamp':desc))&_g=(time:(from:now-24h,mode:quick,to:now))"
|
||||
>
|
||||
Go to Discover
|
||||
</a>
|
||||
|
|
|
@ -191,7 +191,7 @@ describe('UnconnectedKibanaLink', () => {
|
|||
interval: 'auto',
|
||||
query: {
|
||||
language: 'lucene',
|
||||
query: `context.service.name:myServiceName AND error.grouping_key:myGroupId`
|
||||
query: `context.service.name:"myServiceName" AND error.grouping_key:"myGroupId"`
|
||||
},
|
||||
sort: { '@timestamp': 'desc' }
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ describe('UnconnectedKibanaLink', () => {
|
|||
|
||||
it('should have correct url', () => {
|
||||
expect(wrapper.find('a').prop('href')).toBe(
|
||||
"myBasePath/app/kibana#/discover?_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))&_g="
|
||||
'myBasePath/app/kibana#/discover?_a=(interval:auto,query:(language:lucene,query:\'context.service.name:"myServiceName" AND error.grouping_key:"myGroupId"\'),sort:(\'@timestamp\':desc))&_g=(time:(from:now-24h,mode:quick,to:now))'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { EuiLink, EuiLinkAnchorProps } from '@elastic/eui';
|
||||
import createHistory from 'history/createHashHistory';
|
||||
import _ from 'lodash';
|
||||
import { get, isEmpty, isPlainObject, mapValues } from 'lodash';
|
||||
import qs from 'querystring';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -54,7 +54,7 @@ export function ViewMLJob({
|
|||
);
|
||||
}
|
||||
|
||||
export function toQuery(search?: string) {
|
||||
export function toQuery(search?: string): StringMap<any> {
|
||||
return search ? qs.parse(search.slice(1)) : {};
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ export function fromQuery(query: StringMap) {
|
|||
}
|
||||
|
||||
export function encodeQuery(query: StringMap, exclude: string[] = []) {
|
||||
return _.mapValues(query, (value: any, key: string) => {
|
||||
return mapValues(query, (value: any, key: string) => {
|
||||
if (exclude.includes(key)) {
|
||||
return encodeURI(value);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ function stringifyWithoutEncoding(query: StringMap) {
|
|||
|
||||
function decodeAsObject(value: string) {
|
||||
const decoded = rison.decode(value);
|
||||
return _.isPlainObject(decoded) ? decoded : {};
|
||||
return isPlainObject(decoded) ? decoded : {};
|
||||
}
|
||||
|
||||
export function decodeKibanaSearchParams(search: string) {
|
||||
|
@ -125,15 +125,15 @@ export function RelativeLinkComponent({
|
|||
}
|
||||
|
||||
// Shorthand for pathname
|
||||
const pathname = path || _.get(props.to, 'pathname') || location.pathname;
|
||||
const pathname = path || get(props.to, 'pathname') || location.pathname;
|
||||
|
||||
// Add support for querystring as object
|
||||
const search =
|
||||
query || _.get(props.to, 'query')
|
||||
query || get(props.to, 'query')
|
||||
? fromQuery({
|
||||
...toQuery(location.search),
|
||||
...query,
|
||||
..._.get(props.to, 'query')
|
||||
...get(props.to, 'query')
|
||||
})
|
||||
: location.search;
|
||||
|
||||
|
@ -152,6 +152,17 @@ export function RelativeLinkComponent({
|
|||
// The two components have different APIs: `path` vs `pathname` and one uses EuiLink the other react-router's Link (which behaves differently)
|
||||
// Suggestion: Deprecate RelativeLink, and clean up KibanaLink
|
||||
|
||||
// _g is always retrieved from the url - it can not be changed via query prop
|
||||
function getGArg(g: string) {
|
||||
// use "g" if it's set in the url
|
||||
if (g && !isEmpty(rison.decode(g))) {
|
||||
return g;
|
||||
}
|
||||
|
||||
// use default 24h (default set in: https://github.com/elastic/kibana/blob/e13e47fc4eb6112f2a5401408e9f765eae90f55d/x-pack/plugins/apm/public/utils/timepicker/index.js#L31-L35)
|
||||
return '(time:(from:now-24h,mode:quick,to:now))';
|
||||
}
|
||||
|
||||
export interface KibanaLinkArgs {
|
||||
location: {
|
||||
search?: string;
|
||||
|
@ -171,6 +182,7 @@ export interface KibanaLinkArgs {
|
|||
*
|
||||
* You must remember to pass in location in that case.
|
||||
*/
|
||||
|
||||
export const UnconnectedKibanaLink: React.SFC<KibanaLinkArgs> = ({
|
||||
location,
|
||||
pathname,
|
||||
|
@ -182,7 +194,7 @@ export const UnconnectedKibanaLink: React.SFC<KibanaLinkArgs> = ({
|
|||
const currentQuery = toQuery(location.search);
|
||||
const nextQuery = {
|
||||
...query,
|
||||
_g: query._g ? rison.encode(query._g) : currentQuery._g,
|
||||
_g: getGArg(currentQuery._g),
|
||||
_a: query._a ? rison.encode(query._a) : ''
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue