diff --git a/conf/defaults.ini b/conf/defaults.ini index 55a89dfa205..38ec12ab7e3 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1574,6 +1574,9 @@ enabled = true # set the default offset for the time picker defaultTimeOffset = 1h +# hides the download logs button in Explore +hide_logs_download = false + #################################### Help ############################# [help] # Enable the Help section diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 15247a10908..5c15ff2c0b8 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -1934,6 +1934,10 @@ Enable or disable the Explore section. Default is `enabled`. Set a default time offset from now on the time picker. Default is 1 hour. This setting should be expressed as a duration. Examples: 1h (hour), 1d (day), 1w (week), 1M (month). +#### `hide_logs_download` + +Show or hide the button to download logs in Explore. Default is `false`, so that the button will be visible. + ### `[help]` Configures the help section. diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 560f4ba672f..4e57dd61656 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -238,6 +238,7 @@ export interface GrafanaConfig { listScopesEndpoint?: string; reportingStaticContext?: Record; exploreDefaultTimeOffset?: string; + exploreHideLogsDownload?: boolean; // The namespace to use for kubernetes apiserver requests namespace: string; diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index 6b29cdc0dee..dd179ea36a6 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -203,6 +203,7 @@ export class GrafanaBootConfig implements GrafanaConfig { cloudMigrationPollIntervalMs = 2000; reportingStaticContext?: Record; exploreDefaultTimeOffset = '1h'; + exploreHideLogsDownload: boolean | undefined; /** * Language used in Grafana's UI. This is after the user's preference (or deteceted locale) is resolved to one of diff --git a/pkg/api/dtos/frontend_settings.go b/pkg/api/dtos/frontend_settings.go index 6827525be04..30a80ea8b71 100644 --- a/pkg/api/dtos/frontend_settings.go +++ b/pkg/api/dtos/frontend_settings.go @@ -212,6 +212,7 @@ type FrontendSettingsDTO struct { CSPReportOnlyEnabled bool `json:"cspReportOnlyEnabled"` EnableFrontendSandboxForPlugins []string `json:"enableFrontendSandboxForPlugins"` ExploreDefaultTimeOffset string `json:"exploreDefaultTimeOffset"` + ExploreHideLogsDownload bool `json:"ExploreHideLogsDownload"` Auth FrontendSettingsAuthDTO `json:"auth"` diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 8ec544337b0..ba0f2f436bd 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -247,6 +247,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro LocalFileSystemAvailable: hs.Cfg.LocalFileSystemAvailable, ReportingStaticContext: hs.Cfg.ReportingStaticContext, ExploreDefaultTimeOffset: hs.Cfg.ExploreDefaultTimeOffset, + ExploreHideLogsDownload: hs.Cfg.ExploreHideLogsDownload, DefaultDatasourceManageAlertsUIToggle: hs.Cfg.DefaultDatasourceManageAlertsUIToggle, diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 6bb86697f10..d70029b4b20 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -511,6 +511,7 @@ type Cfg struct { // Explore UI ExploreEnabled bool ExploreDefaultTimeOffset string + ExploreHideLogsDownload bool // Help UI HelpEnabled bool @@ -1214,6 +1215,7 @@ func (cfg *Cfg) parseINIFile(iniFile *ini.File) error { } else { cfg.ExploreDefaultTimeOffset = exploreDefaultTimeOffset } + cfg.ExploreHideLogsDownload = explore.Key("hide_logs_download").MustBool(false) help := iniFile.Section("help") cfg.HelpEnabled = help.Key("enabled").MustBool(true) diff --git a/public/app/features/explore/Logs/LogsMetaRow.test.tsx b/public/app/features/explore/Logs/LogsMetaRow.test.tsx index 4774402dbc0..ce63d19b4d0 100644 --- a/public/app/features/explore/Logs/LogsMetaRow.test.tsx +++ b/public/app/features/explore/Logs/LogsMetaRow.test.tsx @@ -5,6 +5,7 @@ import { ComponentProps } from 'react'; import { FieldType, LogLevel, LogsDedupStrategy, standardTransformersRegistry, toDataFrame } from '@grafana/data'; import { organizeFieldsTransformer } from '@grafana/data/src/transformations/transformers/organize'; +import { config } from '@grafana/runtime'; import { MAX_CHARACTERS } from '../../logs/components/LogRowMessage'; import { logRowsToReadableJson } from '../../logs/utils'; @@ -32,11 +33,12 @@ const defaultProps: LogsMetaRowProps = { clearDetectedFields: jest.fn(), }; -const setup = (propOverrides?: object) => { +const setup = (propOverrides?: object, disableDownload = false) => { const props = { ...defaultProps, ...propOverrides, }; + config.exploreHideLogsDownload = disableDownload; return render(); }; @@ -121,6 +123,11 @@ describe('LogsMetaRow', () => { expect(screen.getByText('Download').closest('button')).toBeInTheDocument(); }); + it('does not render a button to show the download menu if disabled', async () => { + setup({}, true); + expect(screen.queryByText('Download')).toBeNull(); + }); + it('renders a button to show the download menu', async () => { setup(); diff --git a/public/app/features/explore/Logs/LogsMetaRow.tsx b/public/app/features/explore/Logs/LogsMetaRow.tsx index abf22494946..9db3be0ebdd 100644 --- a/public/app/features/explore/Logs/LogsMetaRow.tsx +++ b/public/app/features/explore/Logs/LogsMetaRow.tsx @@ -16,7 +16,7 @@ import { Labels, } from '@grafana/data'; import { DataFrame } from '@grafana/data/'; -import { reportInteraction } from '@grafana/runtime'; +import { config, reportInteraction } from '@grafana/runtime'; import { Button, Dropdown, Menu, ToolbarButton, Tooltip, useStyles2 } from '@grafana/ui'; import { downloadDataFrameAsCsv, downloadLogsModelAsTxt } from '../../inspector/utils/download'; @@ -182,11 +182,13 @@ export const LogsMetaRow = memo( }; })} /> - - - Download - - + {!config.exploreHideLogsDownload && ( + + + Download + + + )} )} diff --git a/public/app/features/inspector/InspectDataTab.test.tsx b/public/app/features/inspector/InspectDataTab.test.tsx index a19b4667437..3e7340d6733 100644 --- a/public/app/features/inspector/InspectDataTab.test.tsx +++ b/public/app/features/inspector/InspectDataTab.test.tsx @@ -4,6 +4,7 @@ import { ComponentProps } from 'react'; import { Props } from 'react-virtualized-auto-sizer'; import { DataFrame, FieldType } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { InspectDataTab } from './InspectDataTab'; @@ -75,6 +76,8 @@ describe('InspectDataTab', () => { expect(screen.getByText(/Second data frame/i)).toBeInTheDocument(); }); it('should show download logs button if logs data', () => { + const oldConfig = config.exploreHideLogsDownload; + config.exploreHideLogsDownload = false; const dataWithLogs = [ { name: 'Data frame with logs', @@ -91,6 +94,28 @@ describe('InspectDataTab', () => { ] as unknown as DataFrame[]; render(); expect(screen.getByText(/Download logs/i)).toBeInTheDocument(); + config.exploreHideLogsDownload = oldConfig; + }); + it('should not show download logs button if logs data but config disabled', () => { + const oldConfig = config.exploreHideLogsDownload; + config.exploreHideLogsDownload = true; + const dataWithLogs = [ + { + name: 'Data frame with logs', + fields: [ + { name: 'time', type: FieldType.time, values: [100, 200, 300], config: {} }, + { name: 'name', type: FieldType.string, values: ['uniqueA', 'b', 'c'], config: {} }, + { name: 'value', type: FieldType.number, values: [1, 2, 3], config: {} }, + ], + length: 3, + meta: { + preferredVisualisationType: 'logs', + }, + }, + ] as unknown as DataFrame[]; + render(); + expect(screen.queryByText(/Download logs/i)).not.toBeInTheDocument(); + config.exploreHideLogsDownload = oldConfig; }); it('should not show download logs button if no logs data', () => { render(); diff --git a/public/app/features/inspector/InspectDataTab.tsx b/public/app/features/inspector/InspectDataTab.tsx index dcecf5386dc..49bae7ddbed 100644 --- a/public/app/features/inspector/InspectDataTab.tsx +++ b/public/app/features/inspector/InspectDataTab.tsx @@ -223,7 +223,7 @@ export class InspectDataTab extends PureComponent { - {hasLogs && ( + {hasLogs && !config.exploreHideLogsDownload && (