diff --git a/apps/studio/components/interfaces/LogDrains/LogDrainDestinationSheetForm.tsx b/apps/studio/components/interfaces/LogDrains/LogDrainDestinationSheetForm.tsx index af63cfe8b12..5b33c2ec5a6 100644 --- a/apps/studio/components/interfaces/LogDrains/LogDrainDestinationSheetForm.tsx +++ b/apps/studio/components/interfaces/LogDrains/LogDrainDestinationSheetForm.tsx @@ -34,17 +34,19 @@ import { z } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' import { useForm } from 'react-hook-form' import toast from 'react-hot-toast' -import { useEffect, useState } from 'react' +import { ReactNode, useEffect, useState } from 'react' import { TrashIcon } from 'lucide-react' import { LogDrainData, useLogDrainsQuery } from 'data/log-drains/log-drains-query' -import { InfoTooltip } from 'ui-patterns/info-tooltip' +import Link from 'next/link' +import { Select, SelectContent, SelectItem, SelectTrigger } from '@ui/components/shadcn/ui/select' +import { FormDescription } from '@ui/components/shadcn/ui/form' const FORM_ID = 'log-drain-destination-form' const formUnion = z.discriminatedUnion('type', [ z.object({ type: z.literal('webhook'), - url: z.string().url('Webhook URL is required and must be a valid URL'), + url: z.string().url('Endpoint URL is required and must be a valid URL'), http: z.enum(['http1', 'http2']), gzip: z.boolean(), headers: z.record(z.string(), z.string()).optional(), @@ -56,9 +58,6 @@ const formUnion = z.discriminatedUnion('type', [ }), z.object({ type: z.literal('elastic'), - url: z.string().url({ message: 'URL is required and must be a valid URL' }), - username: z.string().min(1, { message: 'Username is required' }), - password: z.string().min(1, { message: 'Password is required' }), }), z.object({ type: z.literal('postgres'), @@ -90,7 +89,7 @@ function LogDrainFormItem({ label: string formControl: any placeholder?: string - description?: string + description?: ReactNode type?: string defaultValue?: string }) { @@ -131,6 +130,13 @@ export function LogDrainDestinationSheetForm({ onSubmit: (values: z.infer) => void mode: 'create' | 'update' }) { + const CREATE_DEFAULT_HEADERS = { + 'Content-Type': 'application/json', + } + + const DEFAULT_HEADERS = + mode === 'create' ? CREATE_DEFAULT_HEADERS : defaultValues?.config?.headers || {} + const { ref } = useParams() const { data: logDrains } = useLogDrainsQuery({ ref, @@ -147,12 +153,10 @@ export function LogDrainDestinationSheetForm({ type: defaultType, http: defaultValues?.config?.http || 'http2', gzip: defaultValues?.config?.gzip || true, - headers: defaultValues?.config?.headers || {}, + headers: DEFAULT_HEADERS, url: defaultValues?.config?.url || '', api_key: defaultValues?.config?.api_key || '', region: defaultValues?.config?.region || '', - username: defaultValues?.config?.username || '', - password: defaultValues?.config?.password || '', }, }) @@ -207,7 +211,7 @@ export function LogDrainDestinationSheetForm({ Add destination - +
-
+
*/} {mode === 'create' && ( - form.setValue('type', v)} - > - {LOG_DRAIN_TYPES.map((type) => ( - - ))} - + + + )}
-
+
{type === 'webhook' && ( <> - - ( - - - - - - - - - - - - - - - - - - )} - /> +
+ + ( + + + + + + + + + + + + + + + + + + )} + /> +
{/* */} -
- Custom Headers - {hasHeaders && - Object.keys(headers || {})?.map((headerKey) => ( -
-
{headerKey}
-
- {headers?.[headerKey]} +
+
+ Custom Headers +

+ Set custom headers when draining logs to the Endpoint URL +

+
+
+ {hasHeaders && + Object.keys(headers || {})?.map((headerKey) => ( +
+
{headerKey}
+
+ {headers?.[headerKey]} +
+
- -
- ))} + ))} +
)} {type === 'datadog' && ( -
+
+ The API Key obtained from the Datadog dashboard{' '} + + here + + + } />
)} - {type === 'elastic' && ( -
- - - -
- )}
@@ -397,17 +416,23 @@ export function LogDrainDestinationSheetForm({ e.stopPropagation() addHeader() }} - className="flex gap-2 mt-2 items-center" + className="flex gap-2 mt-4 items-center px-content" > + setNewCustomHeader({ ...newCustomHeader, name: e.target.value })} /> + - + + + diff --git a/apps/studio/components/interfaces/LogDrains/LogDrains.constants.tsx b/apps/studio/components/interfaces/LogDrains/LogDrains.constants.tsx index a268538165b..5263d52bd75 100644 --- a/apps/studio/components/interfaces/LogDrains/LogDrains.constants.tsx +++ b/apps/studio/components/interfaces/LogDrains/LogDrains.constants.tsx @@ -1,33 +1,29 @@ -import { Computer, DogIcon, WebhookIcon } from 'lucide-react' +import { BracesIcon, DogIcon } from 'lucide-react' const iconProps = { size: 24, strokeWidth: 1.5, className: 'text-foreground-light' } export const LOG_DRAIN_TYPES = [ { value: 'webhook', - name: 'Webhook', - description: 'Forward logs to a custom HTTP endpoint', - icon: , + name: 'Endpoint', + description: 'Forward logs as a POST request to a custom HTTP endpoint', + icon: , }, { value: 'datadog', - name: 'Data dog', + name: 'Datadog', description: 'Datadog is a monitoring service for cloud-scale applications', icon: , }, - { - value: 'elastic', - name: 'Elastic Filebeat', - description: 'Filebeat is a lightweight shipper for forwarding and centralizing log data', - icon: , - }, ] as const export const LOG_DRAIN_SOURCE_VALUES = LOG_DRAIN_TYPES.map((source) => source.value) -// Added postgres and bigquery here because the generated api types require them but they're not available yet. -// Once we add them they can be removed from this type and added to the LOG_DRAIN_TYPES array. -export type LogDrainType = (typeof LOG_DRAIN_TYPES)[number]['value'] | 'postgres' | 'bigquery' +export type LogDrainType = + | (typeof LOG_DRAIN_TYPES)[number]['value'] + | 'postgres' + | 'bigquery' + | 'elastic' export const DATADOG_REGIONS = [ { @@ -61,12 +57,6 @@ export type LogDrainDatadogConfig = { region: string } -export type LogDrainElasticConfig = { - url: string - username: string - password: string -} - export type LogDrainWebhookConfig = { url: string }