Skip to content

Commit

Permalink
Make log limits configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
ddelemeny committed Apr 9, 2024
1 parent 6bafb31 commit 3e51682
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 12 deletions.
29 changes: 24 additions & 5 deletions src/components/QueryEditor/ElasticsearchQueryContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { createContext, PropsWithChildren, useCallback, useEffect, useState } from 'react';
import React, { createContext, PropsWithChildren, useCallback, useEffect, useState, FunctionComponent } from 'react';

import { CoreApp, TimeRange } from '@grafana/data';

Expand All @@ -10,6 +10,9 @@ import { createReducer as createBucketAggsReducer } from './BucketAggregationsEd
import { reducer as metricsReducer } from './MetricAggregationsEditor/state/reducer';
import { aliasPatternReducer, queryReducer, initQuery, initExploreQuery } from './state';
import { getHook } from '@/utils/context';
import { Provider, useDispatch } from "react-redux";
import { initDefaults } from '@/store/defaults';
import { store } from "@/store"

export const RangeContext = createContext<TimeRange | undefined>(undefined);
export const useRange = getHook(RangeContext);
Expand All @@ -29,15 +32,31 @@ interface Props {
range: TimeRange;
}

export const ElasticsearchProvider = ({
function withStore<P extends PropsWithChildren<Props>>(Component: FunctionComponent<P>): FunctionComponent<P>{
const newComp = (props: P) => (
<Provider store={store}>
<Component {...props}/>
</Provider>
)
newComp.displayName = Component.displayName
return newComp
}

export const ElasticsearchProvider = withStore(({
children,
onChange,
onRunQuery,
query,
app,
datasource,
range,
}: PropsWithChildren<Props>) => {
}: PropsWithChildren<Props>): JSX.Element => {

const storeDispatch = useDispatch();
useEffect(()=>{
storeDispatch(initDefaults(datasource.queryEditorConfig?.defaults))
}, [storeDispatch, datasource])

const onStateChange = useCallback(
(query: ElasticsearchQuery) => {
onChange(query);
Expand Down Expand Up @@ -77,7 +96,7 @@ export const ElasticsearchProvider = ({
}, [shouldRunInit, dispatch, isUninitialized, app]);

if (isUninitialized) {
return null;
return (<></>);
}

return (
Expand All @@ -89,4 +108,4 @@ export const ElasticsearchProvider = ({
</QueryContext.Provider>
</DatasourceContext.Provider>
);
};
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Action } from '@reduxjs/toolkit';
import { defaultLogsAgg, defaultMetricAgg } from '@/queryDef';
import { defaultMetricAgg } from '@/queryDef';
import { ElasticsearchQuery, MetricAggregation } from '@/types';
import { removeEmpty } from '@/utils';
import { initExploreQuery, initQuery } from '../../state';
Expand All @@ -17,7 +17,11 @@ import {
toggleMetricVisibility,
} from './actions';

import { store } from "@/store"

export const reducer = (state: ElasticsearchQuery['metrics'], action: Action): ElasticsearchQuery['metrics'] => {
const defaultsMetricAggregation = store.getState().defaults.metricAggregation;

if (addMetric.match(action)) {
return [...state!, defaultMetricAgg(action.payload)];
}
Expand Down Expand Up @@ -55,7 +59,7 @@ export const reducer = (state: ElasticsearchQuery['metrics'], action: Action): E
return {
id: metric.id,
type: action.payload.type,
...metricAggregationConfig[action.payload.type].defaults,
...defaultsMetricAggregation[action.payload.type as keyof typeof defaultsMetricAggregation],
} as MetricAggregation;
});
}
Expand Down Expand Up @@ -164,7 +168,7 @@ export const reducer = (state: ElasticsearchQuery['metrics'], action: Action): E
if (state && state.length > 0) {
return state;
}
return [defaultLogsAgg('3')];
return [{ type: 'logs', id: '3', ...defaultsMetricAggregation.logs }];
}

return state;
Expand Down
1 change: 1 addition & 0 deletions src/components/QueryEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const ElasticSearchQueryField = ({ value, onChange, onSubmit }: ElasticSe
};

const QueryEditorForm = ({ value, onRunQuery }: Props) => {

const dispatch = useDispatch();
const nextId = useNextId();
const styles = useStyles2(getStyles);
Expand Down
12 changes: 12 additions & 0 deletions src/configuration/ConfigEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { QuickwitOptions } from '../quickwit';
import { coerceOptions } from './utils';
import { Divider } from '../components/Divider';
import { DataLinks } from './DataLinks';
import _ from 'lodash';

interface Props extends DataSourcePluginOptionsEditorProps<QuickwitOptions> {}

Expand Down Expand Up @@ -92,6 +93,17 @@ export const QuickwitDetails = ({ value, onChange }: DetailsProps) => {
/>
</InlineField>
</FieldSet>
<FieldSet label="Editor settings">
<InlineField label="Default logs limit" labelWidth={26} tooltip="The log level field must be a fast field">
<Input
id="quickwit_defaults_metricaggregation_logs_limit"
value={value.jsonData.queryEditorConfig?.defaults?.['metricAggregation.logs.settings.limit']}
onChange={(event) => onChange(_.merge(value, {jsonData:{queryEditorConfig:{defaults:{'metricAggregation.logs.settings.limit':event.currentTarget.value}}}}))}
placeholder="100"
width={40}
/>
</InlineField>
</FieldSet>
</div>
</>
);
Expand Down
5 changes: 5 additions & 0 deletions src/datasource/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { SECOND } from 'utils/time';
import { GConstructor } from 'utils/mixins';
import { LuceneQuery } from '@/utils/lucene';
import { uidMaker } from "@/utils/uid"
import { DefaultsConfigOverrides } from 'store/defaults/conf';

export type BaseQuickwitDataSourceConstructor = GConstructor<BaseQuickwitDataSource>

Expand All @@ -59,6 +60,9 @@ export class BaseQuickwitDataSource
logMessageField?: string;
logLevelField?: string;
dataLinks: DataLinkConfig[];
queryEditorConfig?: {
defaults?: DefaultsConfigOverrides
};
languageProvider: ElasticsearchLanguageProvider;


Expand All @@ -73,6 +77,7 @@ export class BaseQuickwitDataSource
this.logMessageField = settingsData.logMessageField || '';
this.logLevelField = settingsData.logLevelField || '';
this.dataLinks = settingsData.dataLinks || [];
this.queryEditorConfig = settingsData.queryEditorConfig || {};
this.languageProvider = new ElasticsearchLanguageProvider(this);
this.annotations = {};
}
Expand Down
4 changes: 0 additions & 4 deletions src/queryDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ export function defaultMetricAgg(id = '1'): MetricAggregation {
return { type: 'count', id };
}

export function defaultLogsAgg(id = '1'): MetricAggregation {
return { type: 'logs', id, ...metricAggregationConfig['logs'].defaults };
}

export function defaultBucketAgg(id = '1'): DateHistogram {
return { type: 'date_histogram', id, settings: { interval: 'auto' } };
}
Expand Down
4 changes: 4 additions & 0 deletions src/quickwit.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DataSourceJsonData } from "@grafana/data";
import { DataLinkConfig } from "./types";
import { DefaultsConfigOverrides } from "store/defaults/conf";

export interface QuickwitOptions extends DataSourceJsonData {
timeField: string;
Expand All @@ -8,4 +9,7 @@ export interface QuickwitOptions extends DataSourceJsonData {
logLevelField?: string;
dataLinks?: DataLinkConfig[];
index: string;
queryEditorConfig?: {
defaults?: DefaultsConfigOverrides
}
}
40 changes: 40 additions & 0 deletions src/store/defaults/conf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
MetricAggregation,
MetricAggregationType,
Logs as SchemaLogs,
} from '@/dataquery.gen';
import { Logs, LogsSortDirection } from "@/types";

export type QuickwitMetricAggregationType = Extract<'count' | 'avg' | 'sum' | 'min' | 'max' | 'percentiles' | 'raw_data' | 'logs', MetricAggregationType >

export type MetricsDefaultSettings = Partial<{
[T in QuickwitMetricAggregationType]: Omit<Extract<Exclude<MetricAggregation,SchemaLogs>|Logs, { type: T }>, 'id' | 'type'>;
}>;


export const defaultMetricAggregationConfig: MetricsDefaultSettings = {
percentiles: {
settings: {
percents: ['25', '50', '75', '95', '99'],
},
},
raw_data: {
settings: {
size: '100',
},
},
logs: {
settings: {
limit: '100',
sortDirection:'desc' as LogsSortDirection
},
},
};

export const defaultConfig = {
metricAggregation: defaultMetricAggregationConfig
};

export type DefaultsConfig = typeof defaultConfig

export type DefaultsConfigOverrides = {[key: string]: any};
33 changes: 33 additions & 0 deletions src/store/defaults/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { defaultConfig , DefaultsConfigOverrides } from "./conf";
import _ from "lodash";

export const initialState = defaultConfig

const defaultsSlice = createSlice({
name: "defaults",
initialState: defaultConfig,
reducers: {
initDefaults(_s, action: PayloadAction<DefaultsConfigOverrides | undefined>) {
// Initialize from default state, dont keep the old one
let newState = _.cloneDeep(defaultConfig);
// override values with payload
if (action.payload) {
const overrides = action.payload;
for (const key in overrides) {
// XXX : this is very not type-safe. Can do better ?
const value = overrides[key];
newState = _.set(newState, key, value);
}
}
return newState
}
}
})

const {actions, reducer} = defaultsSlice
export const {
initDefaults,
} = actions

export default reducer;
13 changes: 13 additions & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { configureStore } from "@reduxjs/toolkit";
import defaultsReducer from "./defaults"

export const store = configureStore({
reducer: {
defaults: defaultsReducer,
}
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

0 comments on commit 3e51682

Please sign in to comment.