[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:
Søren Louv-Jansen 2018-11-01 11:25:07 +01:00 committed by GitHub
parent 2fb2bda157
commit 704cf6182f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 30 deletions

View file

@ -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",

View file

@ -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}` : ``
}`
},

View file

@ -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}
/>
);

View file

@ -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}"`
}
}
};

View file

@ -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;

View file

@ -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>

View file

@ -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))'
);
});

View file

@ -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) : ''
};