Skip to content

Commit

Permalink
feat(investigations): add button to add logs to an investigation (#1055)
Browse files Browse the repository at this point in the history
* feat(investigations): add button to add logs to an investigation

* Update src/Components/Panels/PanelMenu.tsx

Co-authored-by: Galen Kistler <[email protected]>

* feat(investigations): add `investigationOptions` state to `PanelMenu`

---------

Co-authored-by: Galen Kistler <[email protected]>
  • Loading branch information
svennergr and gtk-grafana authored Feb 11, 2025
1 parent d2eb348 commit 486a882
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 17 deletions.
22 changes: 16 additions & 6 deletions src/Components/Panels/PanelMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,21 @@ export enum CollapsablePanelText {
expanded = 'Expand',
}

interface PanelMenuState extends SceneObjectState {
body?: VizPanelMenu;
frame?: DataFrame;
interface InvestigationOptions {
labelName?: string;
fieldName?: string;
frame?: DataFrame;
type?: 'timeseries' | 'logs';
getLabelName?: () => string;
}

interface PanelMenuState extends SceneObjectState {
body?: VizPanelMenu;
addExplorationsLink?: boolean;
explorationsButton?: AddToExplorationButton;
panelType?: AvgFieldPanelType;

investigationOptions?: InvestigationOptions;
}

/**
Expand Down Expand Up @@ -90,9 +97,12 @@ export class PanelMenu extends SceneObjectBase<PanelMenuState> implements VizPan

this.setState({
explorationsButton: new AddToExplorationButton({
labelName: this.state.labelName,
fieldName: this.state.fieldName,
frame: this.state.frame,
labelName: this.state.investigationOptions?.getLabelName
? this.state.investigationOptions?.getLabelName()
: this.state.investigationOptions?.labelName,
fieldName: this.state.investigationOptions?.fieldName,
frame: this.state.investigationOptions?.frame,
type: this.state.investigationOptions?.type,
}),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AddToExplorationButtonState extends SceneObjectState {
ds?: LokiDatasource;
context?: ExtensionContext;
queries: LokiQuery[];
type?: 'timeseries' | 'logs' | undefined;
}

type ExtensionContext = {
Expand Down Expand Up @@ -74,15 +75,15 @@ export class AddToExplorationButton extends SceneObjectBase<AddToExplorationButt
};

private getContext = () => {
const { queries, ds, labelName, fieldName } = this.state;
const { queries, ds, labelName, fieldName, type } = this.state;
const timeRange = sceneGraph.getTimeRange(this);

if (!timeRange || !queries || !ds?.uid) {
return;
}
const ctx = {
origin: 'Explore Logs',
type: 'timeseries',
type: type ?? 'timeseries',
queries,
timeRange: { ...timeRange.state.value },
datasource: { uid: ds.uid },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export class FieldsAggregatedBreakdownScene extends SceneObjectBase<FieldsAggreg
body = PanelBuilders.timeseries()
.setTitle(labelName)
.setData(dataTransformer)
.setMenu(new PanelMenu({ labelName: labelName }))
.setMenu(new PanelMenu({ investigationOptions: { labelName: labelName } }))
.setCustomFieldConfig('stacking', { mode: StackingMode.Normal })
.setCustomFieldConfig('fillOpacity', 100)
.setCustomFieldConfig('lineWidth', 0)
Expand All @@ -331,7 +331,7 @@ export class FieldsAggregatedBreakdownScene extends SceneObjectBase<FieldsAggreg
body
.setTitle(labelName)
.setData(dataTransformer)
.setMenu(new PanelMenu({ labelName: labelName, panelType }));
.setMenu(new PanelMenu({ investigationOptions: { labelName: labelName }, panelType }));
headerActions.push(
new SelectLabelActionScene({
labelName: String(labelName),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export class LabelsAggregatedBreakdownScene extends SceneObjectBase<LabelsAggreg
// 11.5
// .setShowMenuAlways(true)
.setOverrides(setLevelColorOverrides)
.setMenu(new PanelMenu({ labelName: optionValue }))
.setMenu(new PanelMenu({ investigationOptions: { labelName: optionValue } }))
.setSeriesLimit(MAX_NUMBER_OF_TIME_SERIES)
.build(),
})
Expand Down
7 changes: 6 additions & 1 deletion src/Components/ServiceScene/LogsPanelScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { locationService } from '@grafana/runtime';
import { narrowLogsSortOrder } from '../../services/narrowing';
import { logger } from '../../services/logger';
import { LogsSortOrder } from '@grafana/schema';
import { getPrettyQueryExpr } from 'services/scenes';

interface LogsPanelSceneState extends SceneObjectState {
body?: VizPanel<Options>;
Expand Down Expand Up @@ -234,7 +235,11 @@ export class LogsPanelScene extends SceneObjectBase<LogsPanelSceneState> {
'prettifyLogMessage',
options.prettifyLogMessage ?? Boolean(getLogOption<boolean>('wrapLogMessage', false))
)
.setMenu(new PanelMenu({ addExplorationsLink: false }))
.setMenu(
new PanelMenu({
investigationOptions: { type: 'logs', getLabelName: () => `Logs: ${getPrettyQueryExpr(serviceScene)}` },
})
)
.setOption('showLogContextToggle', true)
// @ts-expect-error Requires Grafana 11.5
.setOption('enableInfiniteScrolling', true)
Expand Down
2 changes: 1 addition & 1 deletion src/Components/ServiceScene/LogsVolumePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class LogsVolumePanel extends SceneObjectBase<LogsVolumePanelState> {
.setTitle(this.getTitle(serviceScene.state.totalLogsCount, serviceScene.state.logsCount))
.setOption('legend', { showLegend: true, calcs: ['sum'], displayMode: LegendDisplayMode.List })
.setUnit('short')
.setMenu(new PanelMenu({ labelName: 'level' }))
.setMenu(new PanelMenu({ investigationOptions: { labelName: 'level' } }))
.setCollapsible(true)
.setCollapsed(Boolean(getLogsVolumeOption('collapsed')))
.setHeaderActions(new LogsVolumeActions({}))
Expand Down
2 changes: 1 addition & 1 deletion src/services/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function getFilterBreakdownValueScene(
})
)
.setOverrides(setLevelColorOverrides)
.setMenu(new PanelMenu({ frame, fieldName: getTitle(frame), labelName: labelKey }))
.setMenu(new PanelMenu({ investigationOptions: { frame, fieldName: getTitle(frame), labelName: labelKey } }))
.setHeaderActions([new AddToFiltersButton({ frame, variableName })]);

if (style === DrawStyle.Bars) {
Expand Down
15 changes: 12 additions & 3 deletions src/services/scenes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { urlUtil } from '@grafana/data';
import { config, getDataSourceSrv } from '@grafana/runtime';
import { sceneGraph, SceneObject, SceneObjectUrlValues, SceneQueryRunner, SceneTimePicker } from '@grafana/scenes';
import { LOG_STREAM_SELECTOR_EXPR, VAR_DATASOURCE_EXPR, VAR_LABELS_EXPR } from './variables';
import {
LOG_STREAM_SELECTOR_EXPR,
PRETTY_LOG_STREAM_SELECTOR_EXPR,
VAR_DATASOURCE_EXPR,
VAR_LABELS_EXPR,
} from './variables';
import { EXPLORATIONS_ROUTE } from './routing';
import { IndexScene } from 'Components/IndexScene/IndexScene';
import { logger } from './logger';
Expand All @@ -19,11 +24,15 @@ export function getDataSource(sceneObject: SceneObject) {
return sceneGraph.interpolate(sceneObject, VAR_DATASOURCE_EXPR);
}

export function getQueryExpr(exploration: IndexScene) {
export function getQueryExpr(exploration: SceneObject) {
return sceneGraph.interpolate(exploration, LOG_STREAM_SELECTOR_EXPR).replace(/\s+/g, ' ');
}

export function getPatternExpr(exploration: IndexScene) {
export function getPrettyQueryExpr(exploration: SceneObject) {
return sceneGraph.interpolate(exploration, PRETTY_LOG_STREAM_SELECTOR_EXPR).replace(/\s+/g, ' ');
}

export function getPatternExpr(exploration: SceneObject) {
return sceneGraph.interpolate(exploration, VAR_LABELS_EXPR).replace(/\s+/g, ' ');
}

Expand Down
1 change: 1 addition & 0 deletions src/services/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const DETECTED_FIELD_AND_METADATA_VALUES_EXPR = `{${VAR_LABELS_EXPR}} ${V
export const DETECTED_METADATA_VALUES_EXPR = `{${VAR_LABELS_EXPR}} ${VAR_LEVELS_EXPR} ${PENDING_FIELDS_EXPR} ${VAR_PATTERNS_EXPR} ${VAR_LINE_FILTERS_EXPR} ${VAR_LOGS_FORMAT_EXPR} ${VAR_FIELDS_EXPR}`;
export const DETECTED_LEVELS_VALUES_EXPR = `{${VAR_LABELS_EXPR}} ${PENDING_FIELDS_EXPR} ${VAR_METADATA_EXPR} ${VAR_PATTERNS_EXPR} ${VAR_LINE_FILTERS_EXPR} ${VAR_LOGS_FORMAT_EXPR} ${VAR_FIELDS_EXPR}`;
export const PATTERNS_SAMPLE_SELECTOR_EXPR = `{${VAR_LABELS_EXPR}} ${VAR_METADATA_EXPR} ${VAR_PATTERNS_EXPR} ${VAR_LOGS_FORMAT_EXPR}`;
export const PRETTY_LOG_STREAM_SELECTOR_EXPR = `${VAR_LABELS_EXPR} ${VAR_LEVELS_EXPR} ${VAR_METADATA_EXPR} ${VAR_PATTERNS_EXPR} ${VAR_LINE_FILTERS_EXPR} ${VAR_FIELDS_EXPR}`;
export const EXPLORATION_DS = { uid: VAR_DATASOURCE_EXPR };
export const ALL_VARIABLE_VALUE = '$__all';
export const LEVEL_VARIABLE_VALUE = 'detected_level';
Expand Down

0 comments on commit 486a882

Please sign in to comment.