Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

Commit

Permalink
[WIP] broken data plugin usage, can't resolve promise
Browse files Browse the repository at this point in the history
Signed-off-by: inge4pres <francesco.gualazzi@elastic.co>
  • Loading branch information
inge4pres committed Mar 4, 2022
1 parent ac06ea3 commit 9d3f241
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 53 deletions.
20 changes: 19 additions & 1 deletion src/plugins/profiling/public/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,18 @@ function App({ fetchTopN, fetchElasticFlamechart, fetchPixiFlamechart, fetchTopN
samples: [],
series: new Map(),
});
const [topnData, setTopNData] = useState({
samples: [],
series: new Map(),
});

const [elasticFlamegraph, setElasticFlamegraph] = useState({ leaves: [] });
const [pixiFlamegraph, setPixiFlamegraph] = useState({});

const tabs = [
{
id: 'stacktrace-elastic',
name: 'Stack Traces (Elastic)',
name: 'Stack Traces (API)',
content: (
<>
<EuiSpacer />
Expand All @@ -57,6 +61,20 @@ function App({ fetchTopN, fetchElasticFlamechart, fetchPixiFlamechart, fetchTopN
</>
),
},
{
id: 'stacktrace-elastic-data',
name: 'Stack Traces (Data Plugin)',
content: (
<>
<EuiSpacer />
<TopNContext.Provider value={topnData}>
<StackTraceNavigation fetchTopN={fetchTopNData} setTopN={setTopNData} />
<StackedBarChart id="topn-data" name="topn-data" height={400} x="x" y="y" category="g" />
<ChartGrid maximum={10} />
</TopNContext.Provider>
</>
),
},
{
id: 'flamegraph-elastic',
name: 'FlameGraph (Elastic)',
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/profiling/public/components/contexts/topn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

import { createContext } from 'react';

export const TopNContext = createContext();
export const TopNContext = createContext({});
20 changes: 13 additions & 7 deletions src/plugins/profiling/public/components/stacktrace-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,19 @@ export const StackTraceNavigation = ({ fetchTopN, setTopN }) => {
});

console.log(new Date().toISOString(), 'started payload retrieval');
fetchTopN(topnValue[0].value, dateValue[0].value).then((response) => {
console.log(new Date().toISOString(), 'finished payload retrieval');
const samples = getTopN(response);
const series = groupSamplesByCategory(samples);
setTopN({ samples, series });
console.log(new Date().toISOString(), 'updated local state');
});
fetchTopN(topnValue[0].value, dateValue[0].value)
.then((response) => {
console.log(new Date().toISOString(), 'finished payload retrieval');
const samples = getTopN(response);
const series = groupSamplesByCategory(samples);
console.log('sample %o', samples);
console.log('series %o', series);
setTopN({ samples, series });
console.log(new Date().toISOString(), 'updated local state');
})
.catch((err) => {
console.log('error when reading topN data: ' + err.message);
});
}, [toggleTopNSelected, toggleDateSelected]);

return (
Expand Down
66 changes: 43 additions & 23 deletions src/plugins/profiling/public/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
import { CoreStart, HttpFetchError, HttpFetchQuery } from 'kibana/public';
import { getRemoteRoutePaths } from '../common';
import { ProdfilerPluginStartDeps } from './plugin';
import { DownsampledRequest, DownsampledTopNResponse } from '../common/types';
import {
DOWNSAMPLED_TOPN_STRATEGY,
DownsampledRequest,
DownsampledTopNResponse,
TopNAggregateResponse,
} from '../common/types';

export interface Services {
fetchTopN: (type: string, seconds: string) => Promise<any[] | HttpFetchError>;
fetchElasticFlamechart: (seconds: string) => Promise<any[] | HttpFetchError>;
fetchPixiFlamechart: (seconds: string) => Promise<any[] | HttpFetchError>;
// FIXME
fetchTopNData?: (searchField: string, seconds: string) => Promise<DownsampledTopNResponse>;
fetchTopNData: (searchField: string, seconds: string) => Promise<TopNAggregateResponse>;
}

function getFetchQuery(seconds: string): HttpFetchQuery {
Expand All @@ -36,28 +40,44 @@ export function getServices(core: CoreStart, data?: ProdfilerPluginStartDeps): S
const paths = getRemoteRoutePaths();

return {
fetchTopNData: (searchField: string, seconds: string): Promise<DownsampledTopNResponse> => {
fetchTopNData: async (searchField: string, seconds: string): Promise<TopNAggregateResponse> => {
const unixTime = Math.floor(Date.now() / 1000);
return (
data!.data.search
.search<DownsampledRequest, DownsampledTopNResponse>(
{
params: {
projectID: 5,
timeFrom: unixTime - parseInt(seconds, 10),
timeTo: unixTime,
// FIXME remove hard-coded value for topN items length and expose it through the UI
topNItems: 100,
searchField,
},
const response: TopNAggregateResponse = { topN: { histogram: { buckets: [] } } };
data!.data.search
.search<DownsampledRequest, DownsampledTopNResponse>(
{
params: {
projectID: 5,
timeFrom: unixTime - parseInt(seconds, 10),
timeTo: unixTime,
// FIXME remove hard-coded value for topN items length and expose it through the UI
topNItems: 100,
searchField,
},
{
strategy: 'downsampledTopN',
}
)
// get the results and prepare the Promise
.toPromise<DownsampledTopNResponse>()
);
},
{
strategy: DOWNSAMPLED_TOPN_STRATEGY,
}
)
.subscribe({
next: (result) => {
console.log('subscription data plugin rawResponse: %o', result.rawResponse);
response.topN.histogram = result.rawResponse.aggregations.histogram;
},
// TODO error handling
error: (err) => {
console.log('subscription error: %o', err);
},
// FIXME remove this, used for debugging only
complete: () => {
console.log('subscription completed');
},
});

console.log('returning Promise of TopNAggregateResponse');
return await new Promise<TopNAggregateResponse>((resolve, _) => {
return resolve(response);
});
},

fetchTopN: async (type: string, seconds: string) => {
Expand Down
57 changes: 36 additions & 21 deletions src/plugins/profiling/server/search/strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,62 @@

import { SearchTotalHits } from '@elastic/elasticsearch/lib/api/types';
import { IEsSearchRequest, ISearchStrategy, PluginStart } from '../../../data/server';
import { autoHistogramSumCountOnGroupByField, newProjectTimeQuery } from '../routes/mappings';
import {
autoHistogramSumCountOnGroupByField,
newProjectTimeQuery,
ProjectTimeQuery,
} from '../routes/mappings';
import { downsampledIndex, getSampledTraceEventsIndex } from '../routes/search_flamechart';
import { DownsampledRequest, DownsampledTopNResponse } from '../../common/types';

export const DownsampledTopNFactory = (
data: PluginStart
): ISearchStrategy<DownsampledRequest, DownsampledTopNResponse> => {
const es = data.search.getSearchStrategy();

// FIXME these 2 constants should be configurable?
const initialExp = 6;
const targetSampleSize = 20000; // minimum number of samples to get statistically sound results

// Calculate the right down-sampled index to query data from
const sampleCountFromInitialExp = (filter: ProjectTimeQuery, options, deps): number => {
// By default, we return no samples and use the un-sampled index
let sampleCount = 0;
es.search(
{
params: {
index: downsampledIndex + initialExp,
body: {
query: filter,
size: 0,
track_total_hits: true,
},
},
},
options,
deps
).subscribe({
next: (value) => {
sampleCount = (value.rawResponse.hits.total as SearchTotalHits).value;
},
});
return sampleCount;
};
return {
search: async (request, options, deps) => {
search: (request, options, deps) => {
const { projectID, timeFrom, timeTo, topNItems, searchField } = request.params!;
const filter = newProjectTimeQuery(
projectID.toString(),
timeFrom.toString(),
timeTo.toString()
);

// FIXME these 2 constants should be configurable?
const initialExp = 6;
const targetSampleSize = 20000; // minimum number of samples to get statistically sound results
// Calculate the right down-sampled index to query data from
const sampleCountFromInitialExp = async (): Promise<number> => {
return await deps.esClient.asInternalUser
.search({
index: downsampledIndex + initialExp,
body: {
query: filter,
size: 0,
track_total_hits: true,
},
})
.then((resp) => {
return (resp.body.hits?.total as SearchTotalHits).value;
});
};
// Create the query for the actual data
const downsampledReq = {
params: {
index: getSampledTraceEventsIndex(
targetSampleSize,
await sampleCountFromInitialExp(),
sampleCountFromInitialExp(filter, options, deps),
initialExp
).name,
body: {
Expand Down

0 comments on commit 9d3f241

Please sign in to comment.