import { useFlag } from 'common' import { BookOpen, Check, ChevronDown, ChevronsUpDown, Copy, ExternalLink, X } from 'lucide-react' import Link from 'next/link' import { ReactNode, useEffect, useState } from 'react' import { logConstants } from 'shared-data' import { Badge, Button, cn, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, copyToClipboard, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Label, Popover, PopoverContent, PopoverTrigger, SidePanel, Switch, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { EXPLORER_DATEPICKER_HELPERS, LOGS_SOURCE_DESCRIPTION, LogsTableName, } from './Logs.constants' import { DatePickerValue, LogsDatePicker } from './Logs.DatePickers' import { LogsWarning, LogTemplate } from './Logs.types' import Table from '@/components/to-be-cleaned/Table' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useShowMultigresLogs } from '@/hooks/misc/useShowMultigresLogs' import { DOCS_URL } from '@/lib/constants' export interface LogsQueryPanelProps { templates?: LogTemplate[] value: DatePickerValue warnings: LogsWarning[] onSelectTemplate: (template: LogTemplate) => void onSelectSource: (source: string) => void onDateChange: (value: DatePickerValue) => void useOtel?: boolean onUseOtelChange?: (value: boolean) => void } function DropdownMenuItemContent({ name, desc }: { name: ReactNode; desc?: string }) { return (
{name}
{desc &&
{desc}
}
) } const LogsQueryPanel = ({ templates = [], value, warnings, onSelectTemplate, onSelectSource, onDateChange, useOtel = false, onUseOtelChange, }: LogsQueryPanelProps) => { const [showReference, setShowReference] = useState(false) const { logsTemplates } = useIsFeatureEnabled(['logs:templates']) const showChToggleInLogExplorer = useFlag('showChToggleInLogExplorer') const otelToggleEnabled = !!showChToggleInLogExplorer && !!onUseOtelChange const { projectAuthAll: authEnabled, projectStorageAll: storageEnabled, projectEdgeFunctionAll: edgeFunctionsEnabled, } = useIsFeatureEnabled(['project_auth:all', 'project_storage:all', 'project_edge_function:all']) const logsTableNames = Object.entries(LogsTableName) .filter(([key]) => { if (key === 'AUTH') return authEnabled if (key === 'STORAGE') return storageEnabled if (key === 'FN_EDGE') return edgeFunctionsEnabled if (key === 'PG_CRON') return false return true }) .map(([, value]) => value) const [selectedDatePickerValue, setSelectedDatePickerValue] = useState(value) useEffect(() => { setSelectedDatePickerValue(value) }, [value.from, value.to, value.text, value.isHelper]) const [open, setOpen] = useState(false) const showMultigresLogs = useShowMultigresLogs() const schemas = logConstants.schemas.filter( (schema) => schema.reference !== 'multigres_logs' || showMultigresLogs ) const [selectedSchema, setSelectedSchema] = useState(schemas[0]) return (
{logsTableNames .sort((a, b) => a.localeCompare(b)) .map((source) => ( onSelectSource(source)}> ))} {logsTemplates && ( {templates .sort((a, b) => a.label!.localeCompare(b.label!)) .map((template) => ( onSelectTemplate(template)} >

{template.label}

))}
)} { setSelectedDatePickerValue(value) onDateChange(value) }} helpers={EXPLORER_DATEPICKER_HELPERS} /> {otelToggleEnabled && (
onUseOtelChange?.(checked)} />
Run this query against the new ClickHouse-backed OTEL endpoint instead of BigQuery. Use to validate ClickHouse SQL before relying on it.
)}
0 ? 'opacity-100' : 'invisible h-0 w-0 opacity-0' }`} > {warnings.length} {warnings.length > 1 ? 'warnings' : 'warning'} {warnings.map((warning, index) => (

{warning.text}{' '} {warning.link && ( {warning.linkText || 'View'} )}

))}

Field Reference

} visible={showReference} cancelText="Close" onCancel={() => setShowReference(false)} hideFooter triggerElement={ } >

The following table shows all the available paths that can be queried from each respective source. Do note that to access nested keys, you would need to perform the necessary{' '} unnesting joins

No source found. {schemas.map((schema) => ( { setSelectedSchema(schema) setOpen(false) }} > {schema.name} ))} Path , Type , ]} body={selectedSchema.fields.map((field) => ( ))} /> ) } const Field = ({ field, }: { field: { path: string type: string } }) => { const [isCopied, setIsCopied] = useState(false) return ( copyToClipboard(field.path, () => { setIsCopied(true) setTimeout(() => setIsCopied(false), 3000) }) } > {field.path} {isCopied ? ( Copied ) : ( Copy value )} {field.type} ) } export default LogsQueryPanel