Skip to content

Commit

Permalink
(dynamic alert thresholds) Force recompilation of Stumpy library duri…
Browse files Browse the repository at this point in the history
…ng bootup (#1140)

Use mode preloading mechanism to force numba compilation for Stumpy
library
  • Loading branch information
ram-senth committed Sep 9, 2024
1 parent 9576dac commit a6dce84
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 17 deletions.
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ services:
- DEV=1
- SEVERITY_ENABLED=1
- GROUPING_ENABLED=1
- ANOMALY_DETECTION_ENABLED=1
- CELERY_WORKER_ENABLE=true
- PORT=9091
- SMOKE_TEST=1
Expand Down
49 changes: 36 additions & 13 deletions src/seer/anomaly_detection/anomaly_detection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import logging
from typing import List, Tuple

import numpy as np
import sentry_sdk
import stumpy # type: ignore # mypy throws "missing library stubs"
from pydantic import BaseModel

from seer.anomaly_detection.accessors import AlertDataAccessor
Expand All @@ -27,6 +29,25 @@


class AnomalyDetection(BaseModel):
@sentry_sdk.trace
def __init__(self):
"""
Force Stumpy compilation by making a dummy call to the library.
Note: compilation triggered here is very specific to the exact values of parameters ignore_trivial, normalize etc. A
future call with different values for one or more parameter will still trigger a recompilation.
"""
data = np.arange(10.0)
mp = stumpy.stump(data, m=3, ignore_trivial=True, normalize=False)
stream = stumpy.stumpi(
data,
m=3,
mp=mp,
normalize=False,
egress=False,
)
stream.update(6.0)

@sentry_sdk.trace
def _batch_detect(
self, timeseries: List[TimeSeriesPoint], config: AnomalyDetectionConfig
Expand Down Expand Up @@ -181,6 +202,7 @@ def _update_anomalies(self, ts_external: List[TimeSeriesPoint], anomalies: TimeS
anomaly_type=anomalies.flags[i],
)

@sentry_sdk.trace
def detect_anomalies(self, request: DetectAnomaliesRequest) -> DetectAnomaliesResponse:
"""
Main entry point for anomaly detection.
Expand All @@ -190,21 +212,22 @@ def detect_anomalies(self, request: DetectAnomaliesRequest) -> DetectAnomaliesRe
Anomaly detection request that has either a complete time series or an alert reference.
"""
if isinstance(request.context, AlertInSeer):
transaction_name = "Stream AD for alert"
mode = "streaming.alert"
elif isinstance(request.context, TimeSeriesWithHistory):
mode = "streaming.ts_with_history"
else:
mode = "batch.ts_full"

sentry_sdk.set_tag("ad_mode", mode)

if isinstance(request.context, AlertInSeer):
ts, anomalies = self._online_detect(request.context, request.config)
elif isinstance(request.context, TimeSeriesWithHistory):
transaction_name = "Stream AD for timeseries with history"
ts, anomalies = self._combo_detect(request.context, request.config)
else:
transaction_name = "Batch AD for timeseries"

with sentry_sdk.start_transaction(op="task", name=transaction_name):
if isinstance(request.context, AlertInSeer):
ts, anomalies = self._online_detect(request.context, request.config)
elif isinstance(request.context, TimeSeriesWithHistory):
ts, anomalies = self._combo_detect(request.context, request.config)
else:
ts, anomalies = self._batch_detect(request.context, request.config)
self._update_anomalies(ts, anomalies)
return DetectAnomaliesResponse(timeseries=ts)
ts, anomalies = self._batch_detect(request.context, request.config)
self._update_anomalies(ts, anomalies)
return DetectAnomaliesResponse(timeseries=ts)

@inject
def store_data(
Expand Down
9 changes: 5 additions & 4 deletions src/seer/bootup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ def bootup(
*, start_model_loading: bool, integrations: list[Integration], config: AppConfig = injected
):
initialize_sentry_sdk(integrations)
initialize_logs(["seer.", "celery_app."])
config.do_validation()
initialize_database()
initialize_models(start_model_loading)
with sentry_sdk.metrics.timing(key="seer_bootup_time"):
initialize_logs(["seer.", "celery_app."])
config.do_validation()
initialize_database()
initialize_models(start_model_loading)


@inject
Expand Down

0 comments on commit a6dce84

Please sign in to comment.