Skip to content

Commit 99dcbfe

Browse files
jordienrjoshenlim
andauthored
add etl logs (supabase#37930)
* add etl logs * fix missing desc * rename to etl-replication-logs * rename sidebar * Add links to ETL logs * Fix * Smol --------- Co-authored-by: Joshen Lim <[email protected]>
1 parent a63e912 commit 99dcbfe

File tree

7 files changed

+82
-12
lines changed

7 files changed

+82
-12
lines changed

apps/studio/components/interfaces/Database/Replication/Pipeline.utils.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,44 @@ export const getStatusName = (
2222
return undefined
2323
}
2424

25-
export const PIPELINE_STATE_MESSAGES = {
25+
const PIPELINE_STATE_MESSAGES = {
2626
enabling: {
27-
title: 'Pipeline Enabling',
27+
title: 'Pipeline enabling',
2828
message: 'Starting the pipeline. Table replication will resume once enabled.',
2929
badge: 'Enabling',
3030
},
3131
disabling: {
32-
title: 'Pipeline Disabling',
32+
title: 'Pipeline disabling',
3333
message: 'Stopping the pipeline. Table replication will be paused once disabled.',
3434
badge: 'Disabling',
3535
},
3636
failed: {
37-
title: 'Pipeline Failed',
38-
message: 'Replication has encountered an error. Check the logs for details.',
37+
title: 'Pipeline failed',
38+
message: 'Replication has encountered an error.',
3939
badge: 'Failed',
4040
},
4141
stopped: {
42-
title: 'Pipeline Stopped',
42+
title: 'Pipeline stopped',
4343
message: 'Replication is paused. Enable the pipeline to resume data synchronization.',
4444
badge: 'Stopped',
4545
},
4646
starting: {
47-
title: 'Pipeline Starting',
47+
title: 'Pipeline starting',
4848
message: 'Initializing replication. Table status will be available once running.',
4949
badge: 'Starting',
5050
},
5151
running: {
52-
title: 'Pipeline Running',
52+
title: 'Pipeline running',
5353
message: 'Replication is active and processing data',
5454
badge: 'Running',
5555
},
5656
unknown: {
57-
title: 'Pipeline Status Unknown',
58-
message: 'Unable to determine replication status. Check the logs for more information.',
57+
title: 'Pipeline status unknown',
58+
message: 'Unable to determine replication status.',
5959
badge: 'Unknown',
6060
},
6161
notRunning: {
62-
title: 'Pipeline Not Running',
62+
title: 'Pipeline not running',
6363
message: 'Replication is not active. Enable the pipeline to start data synchronization.',
6464
badge: 'Disabled',
6565
},

apps/studio/components/interfaces/Database/Replication/PipelineStatus.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useParams } from 'common'
2+
import { InlineLink } from 'components/ui/InlineLink'
13
import { ReplicationPipelineStatusData } from 'data/replication/pipeline-status-query'
24
import { AlertTriangle, Loader2 } from 'lucide-react'
35
import { PipelineStatusRequestStatus } from 'state/replication-pipeline-request-status'
@@ -31,6 +33,8 @@ export const PipelineStatus = ({
3133
isSuccess,
3234
requestStatus,
3335
}: PipelineStatusProps) => {
36+
const { ref } = useParams()
37+
3438
// Map backend statuses to UX-friendly display
3539
const getStatusConfig = () => {
3640
const statusName =
@@ -138,7 +142,17 @@ export const PipelineStatus = ({
138142
<span>{statusConfig.label}</span>
139143
</div>
140144
</TooltipTrigger>
141-
<TooltipContent side="bottom">{statusConfig.tooltip}</TooltipContent>
145+
<TooltipContent side="bottom">
146+
{statusConfig.tooltip}
147+
{['unknown', 'failed'].includes(pipelineStatus?.name ?? '') && (
148+
<>
149+
{' '}
150+
Check the{' '}
151+
<InlineLink href={`/project/${ref}/logs/etl-replication-logs`}>logs</InlineLink> for
152+
more information.
153+
</>
154+
)}
155+
</TooltipContent>
142156
</Tooltip>
143157
)}
144158
</>

apps/studio/components/interfaces/Database/Replication/ReplicationPipelineStatus.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ export const ReplicationPipelineStatus = () => {
174174
}
175175
/>
176176
</div>
177+
<Button asChild type="default">
178+
<Link href={`/project/${projectRef}/logs/etl-replication-logs`}>View logs</Link>
179+
</Button>
177180
<Button
178181
type={statusName === 'stopped' ? 'primary' : 'default'}
179182
onClick={() => onTogglePipeline()}

apps/studio/components/interfaces/Settings/Logs/Logs.constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ export enum LogsTableName {
372372
PGBOUNCER = 'pgbouncer_logs',
373373
PG_UPGRADE = 'pg_upgrade_logs',
374374
PG_CRON = 'pg_cron_logs',
375+
ETL = 'etl_replication_logs',
375376
}
376377

377378
export const LOGS_TABLES = {
@@ -387,6 +388,7 @@ export const LOGS_TABLES = {
387388
pg_upgrade: LogsTableName.PG_UPGRADE,
388389
pg_cron: LogsTableName.POSTGRES,
389390
pgbouncer: LogsTableName.PGBOUNCER,
391+
etl: LogsTableName.ETL,
390392
}
391393

392394
export const LOGS_SOURCE_DESCRIPTION = {
@@ -402,6 +404,7 @@ export const LOGS_SOURCE_DESCRIPTION = {
402404
[LogsTableName.PGBOUNCER]: 'Dedicated connection pooler for PostgreSQL',
403405
[LogsTableName.PG_UPGRADE]: 'Logs generated by the Postgres version upgrade process',
404406
[LogsTableName.PG_CRON]: 'Postgres logs from pg_cron cron jobs',
407+
[LogsTableName.ETL]: 'Logs from the ETL replication process',
405408
}
406409

407410
export const FILTER_OPTIONS: FilterTableSet = {

apps/studio/components/interfaces/Settings/Logs/Logs.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export type QueryType =
9393
| 'pg_upgrade'
9494
| 'pg_cron'
9595
| 'pgbouncer'
96+
| 'etl'
9697

9798
export type Mode = 'simple' | 'custom'
9899

apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
} from 'ui-patterns/InnerSideMenu'
3434
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
3535
import { FeaturePreviewSidebarPanel } from '../../ui/FeaturePreviewSidebarPanel'
36+
import { useReplicationSourcesQuery } from 'data/replication/sources-query'
3637

3738
const SupaIcon = ({ className }: { className?: string }) => {
3839
return (
@@ -91,6 +92,19 @@ export function LogsSidebarMenuV2() {
9192
realtimeAll: realtimeEnabled,
9293
} = useIsFeatureEnabled(['project_storage:all', 'project_auth:all', 'realtime:all'])
9394

95+
const enablePgReplicate = useFlag('enablePgReplicate')
96+
const { data: etlData, isLoading: isETLLoading } = useReplicationSourcesQuery(
97+
{
98+
projectRef: ref,
99+
},
100+
{
101+
enabled: enablePgReplicate,
102+
}
103+
)
104+
105+
// [Jordi] We only want to show ETL logs if the user has the feature enabled AND they're using the feature aka they've created a source.
106+
const showETLLogs = enablePgReplicate && (etlData?.sources?.length ?? 0) > 0 && !isETLLoading
107+
94108
const { plan: orgPlan, isLoading: isOrgPlanLoading } = useCurrentOrgPlan()
95109
const isFreePlan = !isOrgPlanLoading && orgPlan?.id === 'free'
96110

@@ -183,6 +197,14 @@ export function LogsSidebarMenuV2() {
183197
url: `/project/${ref}/logs/pgcron-logs`,
184198
items: [],
185199
},
200+
showETLLogs
201+
? {
202+
name: 'ETL Replication',
203+
key: 'etl_replication_logs',
204+
url: `/project/${ref}/logs/etl-replication-logs`,
205+
items: [],
206+
}
207+
: null,
186208
].filter((x) => x !== null)
187209

188210
const OPERATIONAL_COLLECTIONS = IS_PLATFORM
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { LogsTableName } from 'components/interfaces/Settings/Logs/Logs.constants'
2+
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
3+
import LogsLayout from 'components/layouts/LogsLayout/LogsLayout'
4+
import DefaultLayout from 'components/layouts/DefaultLayout'
5+
import type { NextPageWithLayout } from 'types'
6+
import { useParams } from 'common'
7+
8+
export const LogPage: NextPageWithLayout = () => {
9+
const { ref } = useParams()
10+
11+
return (
12+
<LogsPreviewer
13+
condensedLayout
14+
queryType="etl"
15+
projectRef={ref!}
16+
tableName={LogsTableName.ETL}
17+
/>
18+
)
19+
}
20+
21+
LogPage.getLayout = (page) => (
22+
<DefaultLayout>
23+
<LogsLayout title="ETL Replication Logs">{page}</LogsLayout>
24+
</DefaultLayout>
25+
)
26+
27+
export default LogPage

0 commit comments

Comments
 (0)