Skip to content

Add Get Web hook events API

What does this MR do and why?

Add get web hook events on group and project by REST API

Connected to #437188

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After

How to set up and validate locally

  1. Create web hook event
  2. Request to API
curl --request GET \
  --url http://gdk.test:3000/api/v4/<groups|projects>/<PARENT_ID>/hooks/<HOOK_ID>/events \
  --header 'PRIVATE-TOKEN: <TOKEN>' \

Example query plan from WebHooks::WebHookLogsFinder

Query plans

Example of use:

hook = WebHook.first
user = User.first

WebHooks::WebHookLogsFinder.new(hook, user, hook.parent, { status: ['client_failure', 200, 500] }).execute

Example of raw SQL (8075115 is a webhook ID owned by gitlab-org/gitlab):

SELECT "web_hook_logs".*
FROM   "web_hook_logs"
WHERE  "web_hook_logs"."web_hook_id" = 8075115
       AND ( "web_hook_logs"."response_status" BETWEEN '400' AND '499'
              OR "web_hook_logs"."response_status" = '200'
              OR "web_hook_logs"."response_status" = '500' ) 

Example of query plan:

# In postgres.ai, first create the index being added in this MR:
exec CREATE INDEX web_hook_logs_on_web_hook_id_and_response_status ON ONLY web_hook_logs USING btree (web_hook_id, response_status);

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/28697/commands/89415

 Append  (cost=0.57..46247.79 rows=12050 width=1382) (actual time=11.559..111781.689 rows=77803 loops=1)
   Buffers: shared hit=27 read=78197 dirtied=1642
   I/O Timings: read=110568.641 write=0.000
   ->  Index Scan using web_hook_logs_202402_web_hook_id_created_at_idx on gitlab_partitions_dynamic.web_hook_logs_202402 web_hook_logs_1  (cost=0.57..37136.24 rows=9470 width=1389) (actual time=11.557..30403.693 rows=22217 loops=1)
         Index Cond: (web_hook_logs_1.web_hook_id = 8075115)
         Filter: ((((web_hook_logs_1.response_status)::text >= '400'::text) AND ((web_hook_logs_1.response_status)::text <= '499'::text)) OR ((web_hook_logs_1.response_status)::text = '200'::text) OR ((web_hook_logs_1.response_status)::text = '500'::text))
         Rows Removed by Filter: 4
         Buffers: shared hit=5 read=22318 dirtied=6
         I/O Timings: read=30217.506 write=0.000
   ->  Index Scan using web_hook_logs_202403_web_hook_id_created_at_idx on gitlab_partitions_dynamic.web_hook_logs_202403 web_hook_logs_2  (cost=0.57..2882.54 rows=741 width=1369) (actual time=8.838..21558.973 rows=15551 loops=1)
         Index Cond: (web_hook_logs_2.web_hook_id = 8075115)
         Filter: ((((web_hook_logs_2.response_status)::text >= '400'::text) AND ((web_hook_logs_2.response_status)::text <= '499'::text)) OR ((web_hook_logs_2.response_status)::text = '200'::text) OR ((web_hook_logs_2.response_status)::text = '500'::text))
         Rows Removed by Filter: 1
         Buffers: shared hit=10 read=15622 dirtied=15
         I/O Timings: read=21425.277 write=0.000
   ->  Index Scan using web_hook_logs_202404_web_hook_id_created_at_idx on gitlab_partitions_dynamic.web_hook_logs_202404 web_hook_logs_3  (cost=0.57..3141.61 rows=859 width=1368) (actual time=11.327..29921.386 rows=19370 loops=1)
         Index Cond: (web_hook_logs_3.web_hook_id = 8075115)
         Filter: ((((web_hook_logs_3.response_status)::text >= '400'::text) AND ((web_hook_logs_3.response_status)::text <= '499'::text)) OR ((web_hook_logs_3.response_status)::text = '200'::text) OR ((web_hook_logs_3.response_status)::text = '500'::text))
         Rows Removed by Filter: 6
         Buffers: shared hit=3 read=19486 dirtied=20
         I/O Timings: read=29730.146 write=0.000
   ->  Index Scan using web_hook_logs_202405_web_hook_id_created_at_idx on gitlab_partitions_dynamic.web_hook_logs_202405 web_hook_logs_4  (cost=0.57..3027.14 rows=974 width=1347) (actual time=9.138..29854.263 rows=20665 loops=1)
         Index Cond: (web_hook_logs_4.web_hook_id = 8075115)
         Filter: ((((web_hook_logs_4.response_status)::text >= '400'::text) AND ((web_hook_logs_4.response_status)::text <= '499'::text)) OR ((web_hook_logs_4.response_status)::text = '200'::text) OR ((web_hook_logs_4.response_status)::text = '500'::text))
         Rows Removed by Filter: 17
         Buffers: shared hit=9 read=20771 dirtied=1601
         I/O Timings: read=29195.713 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202406 web_hook_logs_5  (cost=0.00..0.00 rows=1 width=324) (actual time=0.015..0.015 rows=0 loops=1)
         Filter: ((web_hook_logs_5.web_hook_id = 8075115) AND ((((web_hook_logs_5.response_status)::text >= '400'::text) AND ((web_hook_logs_5.response_status)::text <= '499'::text)) OR ((web_hook_logs_5.response_status)::text = '200'::text) OR ((web_hook_logs_5.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202407 web_hook_logs_6  (cost=0.00..0.00 rows=1 width=324) (actual time=0.008..0.008 rows=0 loops=1)
         Filter: ((web_hook_logs_6.web_hook_id = 8075115) AND ((((web_hook_logs_6.response_status)::text >= '400'::text) AND ((web_hook_logs_6.response_status)::text <= '499'::text)) OR ((web_hook_logs_6.response_status)::text = '200'::text) OR ((web_hook_logs_6.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202408 web_hook_logs_7  (cost=0.00..0.00 rows=1 width=324) (actual time=0.007..0.007 rows=0 loops=1)
         Filter: ((web_hook_logs_7.web_hook_id = 8075115) AND ((((web_hook_logs_7.response_status)::text >= '400'::text) AND ((web_hook_logs_7.response_status)::text <= '499'::text)) OR ((web_hook_logs_7.response_status)::text = '200'::text) OR ((web_hook_logs_7.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202409 web_hook_logs_8  (cost=0.00..0.00 rows=1 width=324) (actual time=0.006..0.006 rows=0 loops=1)
         Filter: ((web_hook_logs_8.web_hook_id = 8075115) AND ((((web_hook_logs_8.response_status)::text >= '400'::text) AND ((web_hook_logs_8.response_status)::text <= '499'::text)) OR ((web_hook_logs_8.response_status)::text = '200'::text) OR ((web_hook_logs_8.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202410 web_hook_logs_9  (cost=0.00..0.00 rows=1 width=324) (actual time=0.007..0.007 rows=0 loops=1)
         Filter: ((web_hook_logs_9.web_hook_id = 8075115) AND ((((web_hook_logs_9.response_status)::text >= '400'::text) AND ((web_hook_logs_9.response_status)::text <= '499'::text)) OR ((web_hook_logs_9.response_status)::text = '200'::text) OR ((web_hook_logs_9.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
   ->  Seq Scan on gitlab_partitions_dynamic.web_hook_logs_202411 web_hook_logs_10  (cost=0.00..0.00 rows=1 width=324) (actual time=0.012..0.012 rows=0 loops=1)
         Filter: ((web_hook_logs_10.web_hook_id = 8075115) AND ((((web_hook_logs_10.response_status)::text >= '400'::text) AND ((web_hook_logs_10.response_status)::text <= '499'::text)) OR ((web_hook_logs_10.response_status)::text = '200'::text) OR ((web_hook_logs_10.response_status)::text = '500'::text)))
         Rows Removed by Filter: 0
         I/O Timings: read=0.000 write=0.000
Edited by Jarka Košanová

Merge request reports