U 췀g"@sddlZddlmZmZddlmZddlmZmZddl m Z m Z ddl m Z e rddlmZddl mZmZmZmZdd lmZmZmZed ed efd ZzDdd lmZmZddlmZddlmZm Z ddl!m"Z"m#Z#m$Z$Wne%k redYnXzddl&m'Z'Wne%k r.dZ'YnXddZ(ddZ)ddZ*ddZ+ddZ,ddZ-dd Z.d!d"Z/d#d$Z0d%d&Z1dS)'N)capture_checkin MonitorStatus) DidNotEnable)_get_humanized_interval_now_seconds_since_epoch)loggermatch_regex_list) TYPE_CHECKING)Callable)AnyOptionalTypeVarUnion) MonitorConfigMonitorConfigScheduleTypeMonitorConfigScheduleUnitF.)bound)TaskCelery) Scheduler)crontabschedule) task_failure task_success task_retryzCelery not installed)RedBeatSchedulercCsF|jdpi}d|kr,||d|d=||jdp>i|S)Nheaders properties)requestgetupdate)taskrr#Q/opt/hc_python/lib/python3.8/site-packages/sentry_sdk/integrations/celery/beat.py _get_headers-s r%cCsi}d}d}d}t|tr*d}d|}nLt|trbd}t|j\}}|dkrvtd||iSntdt|iSi|d<||dd<||dd <|dk r||dd <t |d r|j dk rt |j p|j pd |d <|S)Nrzd{0._orig_minute} {0._orig_hour} {0._orig_day_of_month} {0._orig_month_of_year} {0._orig_day_of_week}intervalsecondzIntervals shorter than one minute are not supported by Sentry Crons. Monitor '%s' has an interval of %s seconds. Use the `exclude_beat_tasks` option in the celery integration to exclude it.z8Celery schedule type '%s' not supported by Sentry Crons.rtypevalueunittzUTCtimezone) isinstancerformatrrsecondsrwarningr(hasattrr+strr-)celery_scheduleapp monitor_namemonitor_configZ schedule_typeZschedule_valueZ schedule_unitr#r#r$_get_monitor_config;sT       r8c Cs|js dS|j}t||j}|r$dS|j}|j}t|||}t|}|sLdS|j di} | ||dt ||t j d} | d| i| |jd<dS)zE Add Sentry Crons information to the schedule_entry headers. Nr)sentry-monitor-slugsentry-monitor-config) monitor_slugr7statussentry-monitor-check-in-id)monitor_beat_tasksnamerZexclude_beat_tasksrr5r8booloptionspopr!rrZ IN_PROGRESS) schedulerschedule_entry integrationr6Ztask_should_be_excludedr4r5r7Zis_supported_scheduler check_in_idr#r#r$#_apply_crons_data_to_schedule_entryts8 rGcs2dtk}|rSddlmfdd}|S)aw Makes sure that: - a new Sentry trace is started for each task started by Celery Beat and it is propagated to the task. - the Sentry Crons information is set in the Celery Beat task's headers so that is is monitored with Sentry Crons. After the patched function is called, Celery Beat will call apply_async to put the task in the queue. sentry_patched_schedulerr)CeleryIntegrationcsTt}|dkr ||St}|d|_|\}}t|||||S)Nz celery-beat) sentry_sdkZ get_clientZget_integrationZget_isolation_scopeZset_new_propagation_context_namerG)argskwargsrEscoperCrDrIoriginal_functionr#r$rHs  z6_wrap_beat_scheduler..sentry_patched_scheduler)r3Zsentry_sdk.integrations.celeryrI)rPZalready_patchedrHr#rOr$_wrap_beat_schedulers   rQcCsttjt_dSN)rQrZ apply_entryr#r#r#r$_patch_beat_apply_entrysrScCstdkr dSttjt_dSrR)rrQZ maybe_duer#r#r#r$_patch_redbeat_maybe_duesrTcCs&|r"ttttttdSrR)rconnectcrons_task_successrcrons_task_failurercrons_task_retry)r>r#r#r$_setup_celery_beat_signalss  rYcKshtd|t|}d|kr dS|di}|d}t|d||d|rXtt|ndtjddS)Nzcelery_task_success %sr9r: sentry-monitor-start-timestamp-sr=r;r7rFdurationr<) rdebugr%r rrfloatrOKZsenderrMrr7Zstart_timestamp_sr#r#r$rVs   rVcKshtd|t|}d|kr dS|di}|d}t|d||d|rXtt|ndtjddS)Nzcelery_task_failure %sr9r:rZr=r[ rr]r%r rrr^rERRORr`r#r#r$rWs   rWcKshtd|t|}d|kr dS|di}|d}t|d||d|rXtt|ndtjddS)Nzcelery_task_retry %sr9r:rZr=r[rar`r#r#r$rXs   rX)2rJZsentry_sdk.cronsrrZsentry_sdk.integrationsrZ$sentry_sdk.integrations.celery.utilsrrZsentry_sdk.utilsrrtypingr collections.abcr r r r rZsentry_sdk._typesrrrrZceleryrrZ celery.beatrZcelery.schedulesrrZcelery.signalsrrr ImportErrorZredbeat.schedulersrr%r8rGrQrSrTrYrVrWrXr#r#r#r$s>     9-'