mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-24 18:07:17 +01:00
85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
from datetime import datetime, timedelta
|
|
from typing import Dict
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from celery import shared_task
|
|
|
|
from ee.api.sentry_stats import get_stats_for_timerange
|
|
from posthog.models.feature_flag import FeatureFlag
|
|
from posthog.models.filters.filter import Filter
|
|
from posthog.models.team import Team
|
|
from posthog.queries.trends.trends import Trends
|
|
|
|
|
|
def check_flags_to_rollback():
|
|
flags_with_threshold = FeatureFlag.objects.exclude(rollback_conditions__isnull=True).exclude(
|
|
rollback_conditions__exact=[]
|
|
)
|
|
|
|
for feature_flag in flags_with_threshold:
|
|
check_feature_flag_rollback_conditions(feature_flag_id=feature_flag.pk)
|
|
|
|
|
|
@shared_task(ignore_result=True, max_retries=2)
|
|
def check_feature_flag_rollback_conditions(feature_flag_id: int) -> None:
|
|
flag: FeatureFlag = FeatureFlag.objects.get(pk=feature_flag_id)
|
|
|
|
if any(check_condition(condition, flag) for condition in flag.rollback_conditions):
|
|
flag.performed_rollback = True
|
|
flag.active = False
|
|
flag.save()
|
|
|
|
|
|
def calculate_rolling_average(threshold_metric: Dict, team: Team, timezone: str) -> float:
|
|
curr = datetime.now(tz=ZoneInfo(timezone))
|
|
|
|
rolling_average_days = 7
|
|
|
|
filter = Filter(
|
|
data={
|
|
**threshold_metric,
|
|
"date_from": (curr - timedelta(days=rolling_average_days)).strftime("%Y-%m-%d %H:%M:%S.%f"),
|
|
"date_to": curr.strftime("%Y-%m-%d %H:%M:%S.%f"),
|
|
},
|
|
team=team,
|
|
)
|
|
trends_query = Trends()
|
|
result = trends_query.run(filter, team)
|
|
|
|
if not len(result):
|
|
return False
|
|
|
|
data = result[0]["data"]
|
|
|
|
return sum(data) / rolling_average_days
|
|
|
|
|
|
def check_condition(rollback_condition: Dict, feature_flag: FeatureFlag) -> bool:
|
|
if rollback_condition["threshold_type"] == "sentry":
|
|
created_date = feature_flag.created_at
|
|
base_start_date = created_date.strftime("%Y-%m-%dT%H:%M:%S")
|
|
base_end_date = (created_date + timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S")
|
|
|
|
current_time = datetime.utcnow()
|
|
target_end_date = current_time.strftime("%Y-%m-%dT%H:%M:%S")
|
|
target_start_date = (current_time - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%S")
|
|
|
|
base, target = get_stats_for_timerange(base_start_date, base_end_date, target_start_date, target_end_date)
|
|
|
|
if rollback_condition["operator"] == "lt":
|
|
return target < float(rollback_condition["threshold"]) * base
|
|
else:
|
|
return target > float(rollback_condition["threshold"]) * base
|
|
|
|
elif rollback_condition["threshold_type"] == "insight":
|
|
rolling_average = calculate_rolling_average(
|
|
rollback_condition["threshold_metric"], feature_flag.team, feature_flag.team.timezone
|
|
)
|
|
|
|
if rollback_condition["operator"] == "lt":
|
|
return rolling_average < rollback_condition["threshold"]
|
|
else:
|
|
return rolling_average > rollback_condition["threshold"]
|
|
|
|
return False
|