diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml index ebeb24e31a3e6..b4cc74ff0cd45 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml @@ -3781,6 +3781,66 @@ paths: format: date-time - type: 'null' title: After + - name: dag_id_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Dag Id Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + - name: task_id_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Task Id Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + - name: run_id_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Run Id Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + - name: owner_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Owner Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + - name: event_pattern + in: query + required: false + schema: + anyOf: + - type: string + - type: 'null' + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." + title: Event Pattern + description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ + \ Regular expressions are **not** supported." responses: '200': description: Successful Response diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/event_logs.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/event_logs.py index e721162389991..6e7603121e2ac 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/event_logs.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/event_logs.py @@ -32,7 +32,9 @@ QueryLimit, QueryOffset, SortParam, + _SearchParam, filter_param_factory, + search_param_factory, ) from airflow.api_fastapi.common.router import AirflowRouter from airflow.api_fastapi.core_api.datamodels.event_logs import ( @@ -89,6 +91,7 @@ def get_event_logs( ).dynamic_depends() ), ], + # Exact match filters (for backward compatibility) dag_id: Annotated[FilterParam[str | None], Depends(filter_param_factory(Log.dag_id, str | None))], task_id: Annotated[FilterParam[str | None], Depends(filter_param_factory(Log.task_id, str | None))], run_id: Annotated[FilterParam[str | None], Depends(filter_param_factory(Log.run_id, str | None))], @@ -114,6 +117,12 @@ def get_event_logs( FilterParam[datetime | None], Depends(filter_param_factory(Log.dttm, datetime | None, FilterOptionEnum.GREATER_THAN, "after")), ], + # Pattern search filters (new - for partial matching) + dag_id_pattern: Annotated[_SearchParam, Depends(search_param_factory(Log.dag_id, "dag_id_pattern"))], + task_id_pattern: Annotated[_SearchParam, Depends(search_param_factory(Log.task_id, "task_id_pattern"))], + run_id_pattern: Annotated[_SearchParam, Depends(search_param_factory(Log.run_id, "run_id_pattern"))], + owner_pattern: Annotated[_SearchParam, Depends(search_param_factory(Log.owner, "owner_pattern"))], + event_pattern: Annotated[_SearchParam, Depends(search_param_factory(Log.event, "event_pattern"))], ) -> EventLogCollectionResponse: """Get all Event Logs.""" query = select(Log) @@ -121,6 +130,7 @@ def get_event_logs( statement=query, order_by=order_by, filters=[ + # Exact match filters dag_id, task_id, run_id, @@ -132,6 +142,12 @@ def get_event_logs( included_events, before, after, + # Pattern search filters + dag_id_pattern, + task_id_pattern, + run_id_pattern, + owner_pattern, + event_pattern, ], offset=offset, limit=limit, diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts index 1f2a6bb45bc7f..ba486a353aac5 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts @@ -328,11 +328,13 @@ export const UseEventLogServiceGetEventLogKeyFn = ({ eventLogId }: { export type EventLogServiceGetEventLogsDefaultResponse = Awaited>; export type EventLogServiceGetEventLogsQueryResult = UseQueryResult; export const useEventLogServiceGetEventLogsKey = "EventLogServiceGetEventLogs"; -export const UseEventLogServiceGetEventLogsKeyFn = ({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }: { +export const UseEventLogServiceGetEventLogsKeyFn = ({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }: { after?: string; before?: string; dagId?: string; + dagIdPattern?: string; event?: string; + eventPattern?: string; excludedEvents?: string[]; includedEvents?: string[]; limit?: number; @@ -340,10 +342,13 @@ export const UseEventLogServiceGetEventLogsKeyFn = ({ after, before, dagId, even offset?: number; orderBy?: string[]; owner?: string; + ownerPattern?: string; runId?: string; + runIdPattern?: string; taskId?: string; + taskIdPattern?: string; tryNumber?: number; -} = {}, queryKey?: Array) => [useEventLogServiceGetEventLogsKey, ...(queryKey ?? [{ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }])]; +} = {}, queryKey?: Array) => [useEventLogServiceGetEventLogsKey, ...(queryKey ?? [{ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }])]; export type ExtraLinksServiceGetExtraLinksDefaultResponse = Awaited>; export type ExtraLinksServiceGetExtraLinksQueryResult = UseQueryResult; export const useExtraLinksServiceGetExtraLinksKey = "ExtraLinksServiceGetExtraLinks"; diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts index 4e8aee079327e..2f44048e710b8 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts @@ -626,14 +626,21 @@ export const ensureUseEventLogServiceGetEventLogData = (queryClient: QueryClient * @param data.includedEvents * @param data.before * @param data.after +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.ownerPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.eventPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns EventLogCollectionResponse Successful Response * @throws ApiError */ -export const ensureUseEventLogServiceGetEventLogsData = (queryClient: QueryClient, { after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }: { +export const ensureUseEventLogServiceGetEventLogsData = (queryClient: QueryClient, { after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }: { after?: string; before?: string; dagId?: string; + dagIdPattern?: string; event?: string; + eventPattern?: string; excludedEvents?: string[]; includedEvents?: string[]; limit?: number; @@ -641,10 +648,13 @@ export const ensureUseEventLogServiceGetEventLogsData = (queryClient: QueryClien offset?: number; orderBy?: string[]; owner?: string; + ownerPattern?: string; runId?: string; + runIdPattern?: string; taskId?: string; + taskIdPattern?: string; tryNumber?: number; -} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }) }); +} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }) }); /** * Get Extra Links * Get extra links for task instance. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts index aa3fd9fc85dcb..d91da2d7f0732 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts @@ -626,14 +626,21 @@ export const prefetchUseEventLogServiceGetEventLog = (queryClient: QueryClient, * @param data.includedEvents * @param data.before * @param data.after +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.ownerPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.eventPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns EventLogCollectionResponse Successful Response * @throws ApiError */ -export const prefetchUseEventLogServiceGetEventLogs = (queryClient: QueryClient, { after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }: { +export const prefetchUseEventLogServiceGetEventLogs = (queryClient: QueryClient, { after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }: { after?: string; before?: string; dagId?: string; + dagIdPattern?: string; event?: string; + eventPattern?: string; excludedEvents?: string[]; includedEvents?: string[]; limit?: number; @@ -641,10 +648,13 @@ export const prefetchUseEventLogServiceGetEventLogs = (queryClient: QueryClient, offset?: number; orderBy?: string[]; owner?: string; + ownerPattern?: string; runId?: string; + runIdPattern?: string; taskId?: string; + taskIdPattern?: string; tryNumber?: number; -} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }) }); +} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }) }); /** * Get Extra Links * Get extra links for task instance. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts index 43a4cedca6450..be2271f380feb 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts @@ -626,14 +626,21 @@ export const useEventLogServiceGetEventLog = = unknown[]>({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }: { +export const useEventLogServiceGetEventLogs = = unknown[]>({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }: { after?: string; before?: string; dagId?: string; + dagIdPattern?: string; event?: string; + eventPattern?: string; excludedEvents?: string[]; includedEvents?: string[]; limit?: number; @@ -641,10 +648,13 @@ export const useEventLogServiceGetEventLogs = , "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }, queryKey), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }, queryKey), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }) as TData, ...options }); /** * Get Extra Links * Get extra links for task instance. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts index 312a3196e7a79..59612c368987b 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts @@ -626,14 +626,21 @@ export const useEventLogServiceGetEventLogSuspense = = unknown[]>({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }: { +export const useEventLogServiceGetEventLogsSuspense = = unknown[]>({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }: { after?: string; before?: string; dagId?: string; + dagIdPattern?: string; event?: string; + eventPattern?: string; excludedEvents?: string[]; includedEvents?: string[]; limit?: number; @@ -641,10 +648,13 @@ export const useEventLogServiceGetEventLogsSuspense = , "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }, queryKey), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, event, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, runId, taskId, tryNumber }) as TData, ...options }); +} = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseEventLogServiceGetEventLogsKeyFn({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }, queryKey), queryFn: () => EventLogService.getEventLogs({ after, before, dagId, dagIdPattern, event, eventPattern, excludedEvents, includedEvents, limit, mapIndex, offset, orderBy, owner, ownerPattern, runId, runIdPattern, taskId, taskIdPattern, tryNumber }) as TData, ...options }); /** * Get Extra Links * Get extra links for task instance. diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts index 873f2cfbee206..f04bbe72a787f 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts @@ -1797,6 +1797,11 @@ export class EventLogService { * @param data.includedEvents * @param data.before * @param data.after + * @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.ownerPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.eventPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. * @returns EventLogCollectionResponse Successful Response * @throws ApiError */ @@ -1818,7 +1823,12 @@ export class EventLogService { excluded_events: data.excludedEvents, included_events: data.includedEvents, before: data.before, - after: data.after + after: data.after, + dag_id_pattern: data.dagIdPattern, + task_id_pattern: data.taskIdPattern, + run_id_pattern: data.runIdPattern, + owner_pattern: data.ownerPattern, + event_pattern: data.eventPattern }, errors: { 401: 'Unauthorized', diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts index 74fa8d93c69d9..fb556c127ccde 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts @@ -2500,7 +2500,15 @@ export type GetEventLogsData = { after?: string | null; before?: string | null; dagId?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + dagIdPattern?: string | null; event?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + eventPattern?: string | null; excludedEvents?: Array<(string)> | null; includedEvents?: Array<(string)> | null; limit?: number; @@ -2508,8 +2516,20 @@ export type GetEventLogsData = { offset?: number; orderBy?: Array<(string)>; owner?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + ownerPattern?: string | null; runId?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + runIdPattern?: string | null; taskId?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + taskIdPattern?: string | null; tryNumber?: number | null; }; diff --git a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx index f50957977fc06..50161446b2893 100644 --- a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx @@ -188,15 +188,20 @@ export const Events = () => { { after: afterDate, before: beforeDate, - dagId: dagId ?? dagIdFilter ?? undefined, - event: eventTypeFilter ?? undefined, + // Use exact match for URL params (dag/run/task context) + dagId: dagId ?? undefined, + // Use pattern search for filter inputs (partial matching) + dagIdPattern: dagIdFilter ?? undefined, + eventPattern: eventTypeFilter ?? undefined, limit: pagination.pageSize, mapIndex: mapIndexNumber, offset: pagination.pageIndex * pagination.pageSize, orderBy, - owner: userFilter ?? undefined, - runId: runId ?? runIdFilter ?? undefined, - taskId: taskId ?? taskIdFilter ?? undefined, + ownerPattern: userFilter ?? undefined, + runId: runId ?? undefined, + runIdPattern: runIdFilter ?? undefined, + taskId: taskId ?? undefined, + taskIdPattern: taskIdFilter ?? undefined, tryNumber: tryNumberNumber, }, undefined,