-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ourlogs): Implement the initial version of the logs tab (#83962)
Screenshot, data pulled end-to-end from clickhouse. Search also works. <img width="1035" alt="Screenshot 2025-01-24 at 3 42 04 PM" src="https://github.com/user-attachments/assets/e17cd06a-d24e-4dac-b48e-4b1aabec1f64" />
- Loading branch information
1 parent
53c19e5
commit fd52e4c
Showing
11 changed files
with
218 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import FeatureBadge from 'sentry/components/badge/featureBadge'; | ||
import * as Layout from 'sentry/components/layouts/thirds'; | ||
import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container'; | ||
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; | ||
import {t} from 'sentry/locale'; | ||
import useOrganization from 'sentry/utils/useOrganization'; | ||
import {LogsTabContent} from 'sentry/views/explore/logs/logsTab'; | ||
import {limitMaxPickableDays} from 'sentry/views/explore/utils'; | ||
|
||
export default function LogsPage() { | ||
const organization = useOrganization(); | ||
const {defaultPeriod, maxPickableDays, relativeOptions} = limitMaxPickableDays( | ||
organization! | ||
); | ||
|
||
return ( | ||
<SentryDocumentTitle title={t('Logs')} orgSlug={organization?.slug}> | ||
<PageFiltersContainer maxPickableDays={maxPickableDays}> | ||
<Layout.Page> | ||
<Layout.Header> | ||
<Layout.HeaderContent> | ||
<Layout.Title> | ||
{t('Logs')} | ||
<FeatureBadge type="experimental" /> | ||
</Layout.Title> | ||
</Layout.HeaderContent> | ||
</Layout.Header> | ||
<LogsTabContent | ||
defaultPeriod={defaultPeriod} | ||
maxPickableDays={maxPickableDays} | ||
relativeOptions={relativeOptions} | ||
/> | ||
</Layout.Page> | ||
</PageFiltersContainer> | ||
</SentryDocumentTitle> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,68 @@ | ||
export function LogsTabContent() { | ||
// TODO implement | ||
return <div>logs!</div>; | ||
import {useState} from 'react'; | ||
import styled from '@emotion/styled'; | ||
|
||
import * as Layout from 'sentry/components/layouts/thirds'; | ||
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter'; | ||
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter'; | ||
import PageFilterBar from 'sentry/components/organizations/pageFilterBar'; | ||
import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter'; | ||
import {SearchQueryBuilder} from 'sentry/components/searchQueryBuilder'; | ||
import {t} from 'sentry/locale'; | ||
import {space} from 'sentry/styles/space'; | ||
import {MutableSearch} from 'sentry/utils/tokenizeSearch'; | ||
import {LogsTable} from 'sentry/views/explore/logs/logsTable'; | ||
import type {DefaultPeriod, MaxPickableDays} from 'sentry/views/explore/utils'; | ||
|
||
export type LogsTabProps = { | ||
defaultPeriod: DefaultPeriod; | ||
maxPickableDays: MaxPickableDays; | ||
relativeOptions: Record<string, React.ReactNode>; | ||
}; | ||
|
||
export function LogsTabContent({ | ||
defaultPeriod, | ||
maxPickableDays, | ||
relativeOptions, | ||
}: LogsTabProps) { | ||
const [search, setSearch] = useState(new MutableSearch('')); | ||
return ( | ||
<Layout.Body> | ||
<Layout.Main fullWidth> | ||
<FilterBarContainer> | ||
<PageFilterBar condensed> | ||
<ProjectPageFilter /> | ||
<EnvironmentPageFilter /> | ||
<DatePageFilter | ||
defaultPeriod={defaultPeriod} | ||
maxPickableDays={maxPickableDays} | ||
relativeOptions={({arbitraryOptions}) => ({ | ||
...arbitraryOptions, | ||
...relativeOptions, | ||
})} | ||
/> | ||
</PageFilterBar> | ||
<SearchQueryBuilder | ||
placeholder={t('Search for logs')} | ||
filterKeys={{}} | ||
getTagValues={() => new Promise<string[]>(() => [])} | ||
initialQuery="" | ||
searchSource="ourlogs" | ||
onSearch={query => setSearch(new MutableSearch(query))} | ||
/> | ||
</FilterBarContainer> | ||
</Layout.Main> | ||
<LogsTableContainer fullWidth> | ||
<LogsTable search={search} /> | ||
</LogsTableContainer> | ||
</Layout.Body> | ||
); | ||
} | ||
|
||
const FilterBarContainer = styled('div')` | ||
display: flex; | ||
gap: ${space(2)}; | ||
`; | ||
|
||
const LogsTableContainer = styled(Layout.Main)` | ||
margin-top: ${space(2)}; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import GridEditable from 'sentry/components/gridEditable'; | ||
import TimeSince from 'sentry/components/timeSince'; | ||
import type {MutableSearch} from 'sentry/utils/tokenizeSearch'; | ||
import {useOurlogs} from 'sentry/views/insights/common/queries/useDiscover'; | ||
import type {OurlogsFields} from 'sentry/views/insights/types'; | ||
|
||
export type LogsTableProps = { | ||
search: MutableSearch; | ||
}; | ||
|
||
export function LogsTable(props: LogsTableProps) { | ||
const {data, error, isPending} = useOurlogs( | ||
{ | ||
limit: 100, | ||
sorts: [], | ||
fields: ['sentry.severity_text', 'sentry.body', 'sentry.timestamp'], | ||
search: props.search, | ||
}, | ||
'api.logs-tab.view' | ||
); | ||
return ( | ||
<GridEditable<OurlogsFields, keyof OurlogsFields> | ||
isLoading={isPending} | ||
columnOrder={[ | ||
{key: 'sentry.severity_text', name: 'Severity', width: 60}, | ||
{key: 'sentry.body', name: 'Body', width: 500}, | ||
{key: 'sentry.timestamp', name: 'Timestamp', width: 90}, | ||
]} | ||
columnSortBy={[]} | ||
data={data} | ||
error={error} | ||
grid={{ | ||
renderHeadCell: col => { | ||
return <div>{col.name}</div>; | ||
}, | ||
renderBodyCell: (col, dataRow) => { | ||
if (col.key === 'sentry.timestamp') { | ||
return timestampRenderer(dataRow['sentry.timestamp']); | ||
} | ||
if (col.key === 'sentry.severity_text') { | ||
return severityTextRenderer(dataRow['sentry.severity_text']); | ||
} | ||
return <div>{dataRow[col.key]}</div>; | ||
}, | ||
}} | ||
/> | ||
); | ||
} | ||
|
||
function severityTextRenderer(text: string) { | ||
return <div>{text.toUpperCase().slice(0, 4)}</div>; | ||
} | ||
|
||
function timestampRenderer(timestamp: string) { | ||
return ( | ||
<TimeSince unitStyle="extraShort" date={new Date(timestamp)} tooltipShowSeconds /> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters