Skip to content

Commit

Permalink
Refactor into a proper type, fix other instances of hardcoded values
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle-sammons committed Feb 13, 2024
1 parent 2a6fbbd commit 689ca36
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 18 deletions.
5 changes: 3 additions & 2 deletions src/datasource/components/FieldValueFrequency.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { HorizontalGroup, VerticalGroup, Button } from '@grafana/ui';
interface Props {
field: Field;
children: JSX.Element;
logMessageField: string;
onPlusClick?: (field: Field, value: string) => void;
onMinusClick?: (field: Field, value: string) => void;
}
Expand Down Expand Up @@ -130,9 +131,9 @@ const InnerFooter = (field: Field) => {
/**
* A component to show the FieldValueFrequency for a given field value in the app UI.
*/
const FieldValueFrequency = ({ field, children, onMinusClick, onPlusClick }: Props) => {
const FieldValueFrequency = ({ field, children, onMinusClick, onPlusClick, logMessageField }: Props) => {
// This doesn't make sense for this field
if (field.name === '_source') {
if (field.name === logMessageField) {
return <></>;
}

Expand Down
11 changes: 11 additions & 0 deletions src/datasource/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,14 @@ export interface Field {
}

export type Log = Map<string, any>;

export type DatasourceUserConfig = {
database: string;
flavor: string;
logLevelField: string;
logMessageField: string;
maxConcurrentShardRequests: number;
pplEnabled: boolean;
timeField: string;
version: string;
}
67 changes: 51 additions & 16 deletions src/pages/explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { VariableHide } from '@grafana/schema';
import { Field, Log } from 'datasource/types';
import { Field, Log, DatasourceUserConfig } from 'datasource/types';
import FieldValueFrequency from '../datasource/components/FieldValueFrequency';
import LogsView from 'datasource/components/Logs/LogsView';
import { FixedSizeList as List } from 'react-window'
Expand Down Expand Up @@ -74,6 +74,7 @@ interface FieldStatsState extends SceneObjectState {
topTenMostPopularFields: Field[];
visible: boolean;
loading: boolean;
datasourceUserConfig?: DatasourceUserConfig;
}

interface LogsState extends SceneObjectState {
Expand All @@ -82,6 +83,7 @@ interface LogsState extends SceneObjectState {
loading: boolean;
totalCount: number;
totalFailed: number;
datasourceUserConfig?: DatasourceUserConfig;
}

const NodeStatsRenderer = ({ model }: SceneComponentProps<NodeStats>) => {
Expand Down Expand Up @@ -183,7 +185,7 @@ const KaldbQueryRenderer = ({ model }: SceneComponentProps<KaldbQuery>) => {
);
};

const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[]) => {
const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[], datasourceUserConfig: DatasourceUserConfig) => {
const getIcon = (field: Field): string => {
if (field.type === 'string') {
return 'fa fas fa-font';
Expand Down Expand Up @@ -259,6 +261,7 @@ const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[]) => {
const ListItem = ({ index, data, style }) => {
const field = data.fields[index];
const isTopTenMostPopularField = index <= data.topTenMostPopularFieldsLength;
const logMessageField = data.logMessageField

const isDarkTheme = useTheme2().isDark;
let fieldBackgroundColor = isDarkTheme ? DARK_THEME_BACKGROUND : LIGHT_THEME_BACKGROUND;
Expand All @@ -274,6 +277,7 @@ const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[]) => {

<FieldValueFrequency
field={field}
logMessageField={logMessageField}
onPlusClick={(field: Field, value: string) => queryComponent.appendToQuery(`${field.name}: ${value}`)}
onMinusClick={(field: Field, value: string) =>
queryComponent.appendToQuery(`NOT ${field.name}: ${value}`)
Expand Down Expand Up @@ -316,7 +320,8 @@ const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[]) => {
itemData={
{
fields: [...topTenMostPopularFields, ...fields],
topTenMostPopularFieldsLength: topTenMostPopularFields.length
topTenMostPopularFieldsLength: topTenMostPopularFields.length,
logMessageField: datasourceUserConfig ? datasourceUserConfig.logMessageField : null
}}

itemSize={30}
Expand All @@ -337,7 +342,7 @@ const KalDBFieldsList = (fields: Field[], topTenMostPopularFields: Field[]) => {
};

const KalDBFieldsRenderer = ({ model }: SceneComponentProps<FieldStats>) => {
const { fields, topTenMostPopularFields, visible, loading } = model.useState();
const { fields, topTenMostPopularFields, visible, loading, datasourceUserConfig } = model.useState();

const getFoldIcon = () => {
if (visible) {
Expand Down Expand Up @@ -372,7 +377,7 @@ const KalDBFieldsRenderer = ({ model }: SceneComponentProps<FieldStats>) => {

<Counter value={fields.length} />
</div>
{visible ? KalDBFieldsList(fields, topTenMostPopularFields) : null}
{visible ? KalDBFieldsList(fields, topTenMostPopularFields, datasourceUserConfig) : null}
</div>
)}
</>
Expand All @@ -387,9 +392,16 @@ class FieldStats extends SceneObjectBase<FieldStatsState> {
topTenMostPopularFields: [],
visible: true,
loading: true,
datasourceUserConfig: null,
...state,
});
}
setDatasourceUserConfig= (datasourceUserConfig: DatasourceUserConfig) => {
this.setState({
datasourceUserConfig: datasourceUserConfig,
});
};

setTopTenMostPopularFields = (fields: Field[]) => {
this.setState({
topTenMostPopularFields: fields,
Expand All @@ -416,7 +428,7 @@ class FieldStats extends SceneObjectBase<FieldStatsState> {
}

const KalDBLogsRenderer = ({ model }: SceneComponentProps<KalDBLogs>) => {
const { logs, loading, timestamps } = model.useState();
const { logs, loading, timestamps, datasourceUserConfig } = model.useState();

// TODO: This should be whatever the user set
const timeField = "_timesinceepoch"
Expand All @@ -428,11 +440,6 @@ const KalDBLogsRenderer = ({ model }: SceneComponentProps<KalDBLogs>) => {
let linkedDatasource = null;
let linkedDatasourceName = '';
let linkedDatasourceField = '';
let logMessageField = '';

if (currentDataSource) {
logMessageField = currentDataSource.jsonData.logMessageField;
}

if (currentDataSource && currentDataSource.jsonData.dataLinks?.length > 0) {
linkedDatasourceUid = currentDataSource.jsonData.dataLinks[0].datasourceUid;
Expand Down Expand Up @@ -460,7 +467,7 @@ const KalDBLogsRenderer = ({ model }: SceneComponentProps<KalDBLogs>) => {
datasourceUid={linkedDatasourceUid}
datasourceName={linkedDatasourceName}
datasourceField={linkedDatasourceField}
logMessageField={logMessageField}
logMessageField={datasourceUserConfig ? datasourceUserConfig.logMessageField : ''}
/>
</div>
)}
Expand All @@ -477,10 +484,17 @@ class KalDBLogs extends SceneObjectBase<LogsState> {
totalCount: 0,
totalFailed: 0,
timestamps: [],
datasourceUserConfig: null,
...state,
});
}

setDatasourceUserConfig = (datasourceUserConfig: DatasourceUserConfig) => {
this.setState({
datasourceUserConfig: datasourceUserConfig
});
}

setTimestamps = (timestamps: number[]) => {
this.setState({
timestamps: timestamps,
Expand Down Expand Up @@ -690,24 +704,44 @@ const parseAndExtractLogData = (data: DataFrame[]) => {

// Set field names, the most popular fields, and calculates the frequency of the most common values
if (data.length > 0 && data[0].fields.length > 0) {
const currentDataSource = dataSourceVariable
['getDataSourceTypes']() // This is gross, but we need to access this private property and this is the only real typesafe way to do so in TypeScript
.filter((ele) => ele.name === dataSourceVariable.getValueText())[0];

let datasourceUserConfig: DatasourceUserConfig = null;

if (currentDataSource) {
datasourceUserConfig =
{
database: currentDataSource.jsonData.database,
flavor: currentDataSource.jsonData.flavor,
logLevelField: currentDataSource.jsonData.logLevelField,
logMessageField: currentDataSource.jsonData.logMessageField,
maxConcurrentShardRequests: currentDataSource.jsonData.maxConcurrentShardRequests,
pplEnabled: currentDataSource.jsonData.pplEnabled,
timeField: currentDataSource.jsonData.timeField,
version: currentDataSource.jsonData.version,
};
logsComponent.setDatasourceUserConfig(datasourceUserConfig);
}

let fieldCounts: Map<string, number> = new Map<string, number>();

let mappedFields: Map<string, Field> = new Map<string, Field>();
let reconstructedLogs: Log[] = [...Array(data[0].length)];
let timestamps: number[] = [];

for (let unmappedField of data[0].fields) {
// TODO: Ignore _source for now. We'll likely need to revisit this
// TODO: Ignore the logMessageField (e.g. _source) for now. We'll likely need to revisit this
// when/if we want to support the JSON view
if (unmappedField.name === '_source') {
if (unmappedField.name === logsComponent.state.datasourceUserConfig.logMessageField) {
continue
}

let unmappedFieldValuesArray = unmappedField.values.toArray();
let logsWithDefinedValue = unmappedFieldValuesArray.filter((value) => value !== undefined).length;

// TODO: This should be user configurable
if (unmappedField.name === "_timesinceepoch") {
if (unmappedField.name === logsComponent.state.datasourceUserConfig.timeField) {
timestamps = [ ...unmappedField.values.toArray() ];
}

Expand Down Expand Up @@ -755,6 +789,7 @@ const parseAndExtractLogData = (data: DataFrame[]) => {

fieldComponent.setFields([...mappedFields.values()]);
fieldComponent.setTopTenMostPopularFields(topTenMostPopularFields);
fieldComponent.setDatasourceUserConfig(datasourceUserConfig);
}
return data;
}
Expand Down

0 comments on commit 689ca36

Please sign in to comment.