Skip to content
This repository has been archived by the owner on Sep 12, 2024. It is now read-only.

Commit

Permalink
updated demo to 0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Debanjan Dey authored and Debanjan Dey committed Apr 14, 2022
2 parents 1954e9a + 9f4c5f8 commit c1baf44
Show file tree
Hide file tree
Showing 102 changed files with 4,317 additions and 1,803 deletions.
73 changes: 49 additions & 24 deletions .env
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
# Frontend ENV Variables
# For a more detailed description of the configuration variables please visit: https://docs.chaosgenius.io/docs/Operator_Guides/Configuration/Config%20Parameters

# User Configurable Variables
## Webapp URL
CHAOSGENIUS_WEBAPP_URL=http://localhost:8080/ # URL of the Chaos Genius deployment. Usually, this will be http://<ip-address-or-hostname>:8080/ (http://localhost:8080/ in local installations).

## Analytics
### Common Analytics Configuration
DAYS_OFFSET_FOR_ANALTYICS=2 # Sets the days offset from the current date till which your KPI's will run for.
HOURS_OFFSET_FOR_ANALTYICS=0 # Sets the hours offset from the latest data point till which Anomaly Detection will run for your KPI.
TIMEZONE=UTC # Timezone on which all your analytics are reported.
METADATA_SYNC_TIME=03:00 # Synctime for your metadata

### Anomaly Configuration
MULTIDIM_ANALYSIS_FOR_ANOMALY=False # Enables the generation of multi-dimensional subgroups.
MAX_SUBDIM_CARDINALITY=1000 # Sets the maximum number of unique values allowed in a dimension.
TOP_DIMENSIONS_FOR_ANOMALY_DRILLDOWN=10 # Sets the maximum number of dimensions shown in the Anomaly Drill Downs
MIN_DATA_IN_SUBGROUP=30 # The minimum population in a subgroup.
TOP_SUBDIMENSIONS_FOR_ANOMALY=10 # Sets the maximum number of sud-dimensions shown in the Anomaly Sub-dimensions page.
MAX_FILTER_SUBGROUPS_ANOMALY=250 # Sets the maximum number of subgroups considered for Anomaly Detection
MAX_ANOMALY_SLACK_DAYS=14 # Sets the maximum number of days for which we can have no data and still consider the KPI for Anomaly Detection.

### DeepDrills Configuration
MAX_ROWS_FOR_DEEPDRILLS=10000000 #Sets the maximum number of rows allowed for a KPI to be added.
MAX_DEEPDRILLS_SLACK_DAYS=14 # Sets the maximum number of days for which we can have no data and still consider the KPI for DeepDrills.
DEEPDRILLS_HTABLE_MAX_PARENTS=5 # Sets the maximum number of rows in the first level of the DeepDrills' drilldowns.
DEEPDRILLS_HTABLE_MAX_CHILDREN=5 # Sets the maximum number of rows in the subsequent levels of the DeepDrills' drilldowns.
DEEPDRILLS_HTABLE_MAX_DEPTH=3 # Sets the maximum depth of the drilldowns in DeepDrills.
DEEPDRILLS_ENABLED_TIME_RANGES=last_30_days,last_7_days,previous_day,month_on_month,month_to_date,week_on_week,week_to_date # Sets the enabled time ranges for which DeepDrills is computed as comma separated values.

## Sentry Logging (leave empty to disable backend telemetry)
SENTRY_DSN=

## Enterprise Edition Key
CHAOSGENIUS_ENTERPRISE_EDITION_KEY=

# System Configuration
## Frontend Configuration
REACT_APP_BASE_URL=
REACT_APP_DISABLE_TELEMETRY=false

AIRBYTE_ENABLED=False

## Backend Configuration
### Flask Server
FLASK_APP=run
FLASK_ENV=production
FLASK_DEBUG=0
FLASK_RUN_PORT=5000
SECRET_KEY="t8GIEp8hWmR8y6VLqd6qQCMXzjRaKsx8nRruWNtFuec="
SEND_FILE_MAX_AGE_DEFAULT=31556926

### Database Configuration
DB_HOST=chaosgenius-db
DB_USERNAME=postgres
DB_PASSWORD=chaosgenius
Expand All @@ -23,9 +62,10 @@ INTEGRATION_DB_USERNAME=postgres
INTEGRATION_DB_PASSWORD=chaosgenius
INTEGRATION_DB_PORT=5432
INTEGRATION_DATABASE=chaosgenius_data

#### Celery Configuration
CELERY_RESULT_BACKEND=redis://chaosgenius-redis:6379/1
CELERY_BROKER_URL=redis://chaosgenius-redis:6379/1
CHAOSGENIUS_WEBAPP_URL=http://localhost:8080/

# Alert configuration
## to enable event alerts
Expand All @@ -43,13 +83,17 @@ TASK_CHECKPOINT_LIMIT=1000
# Version identification
CHAOSGENIUS_VERSION_POSTFIX=git

## CG-Airbyte
AIRBYTE_ENABLED=False

# === airbyte env vars start here ===
VERSION=0.29.12-alpha

##########################
# SOURCES LIST
# Set value to 'true' if the source is required, 'false' otherwise.
##########################
# Enabling these data sources requires the third-party version. Please install the third-party version or upgrade to it.
SOURCE_GOOGLE_ANALYTICS=true
SOURCE_GOOGLE_SHEETS=true
SOURCE_MYSQL=false
Expand All @@ -61,6 +105,7 @@ SOURCE_FACEBOOK_ADS=false
SOURCE_BING_ADS=false
SOURCE_GOOGLE_BIG_QUERY=false
SOURCE_SNOWFLAKE=false

# Airbyte Internal Job Database, see https://docs.airbyte.io/operator-guides/configuring-airbyte-db
DATABASE_USER=docker
DATABASE_PASSWORD=docker
Expand Down Expand Up @@ -137,23 +182,3 @@ MAX_SYNC_JOB_ATTEMPTS=3
# Time in days to reach a timeout to cancel the synchronization
MAX_SYNC_TIMEOUT_DAYS=3

#Configurable Analytics Setting
MULTIDIM_ANALYSIS_FOR_ANOMALY=False
MAX_SUBDIM_CARDINALITY=1000
TOP_DIMENSIONS_FOR_ANOMALY_DRILLDOWN=10
MIN_DATA_IN_SUBGROUP=30
TOP_SUBDIMENSIONS_FOR_ANOMALY=10
MAX_ROWS_FOR_DEEPDRILLS=10000000
MAX_FILTER_SUBGROUPS_ANOMALY=250
MAX_DEEPDRILLS_SLACK_DAYS=14
MAX_ANOMALY_SLACK_DAYS=14
DAYS_OFFSET_FOR_ANALTYICS=2
HOURS_OFFSET_FOR_ANALTYICS=0
DEEPDRILLS_HTABLE_MAX_PARENTS=5
DEEPDRILLS_HTABLE_MAX_CHILDREN=5
DEEPDRILLS_HTABLE_MAX_DEPTH=3
DEEPDRILLS_ENABLED_TIME_RANGES=last_30_days,last_7_days,previous_day,month_on_month,month_to_date,week_on_week,week_to_date
TIMEZONE=UTC

SENTRY_DSN=
CHAOSGENIUS_ENTERPRISE_EDITION_KEY=
5 changes: 4 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[flake8]
max-line-length = 88
extend-ignore = E203, E501, D203
exclude =
.git,
__pycache__,
Expand All @@ -9,3 +8,7 @@ exclude =
sandbox
max-complexity = 10
docstring-convention = google
classmethod-decorators =
classmethod
validator
root_validator
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A clear and concise description of what the bug is.
## Explain the environment
- **Chaos Genius version**: example is 0.1.3-alpha
- **OS Version / Instance**: example macOS 11.1, Windows 10, Ubuntu 18.04, AWS EC2
- **Deployment type**: example are Docker or setup from sratch
- **Deployment type**: example are Docker or setup from scratch

## Current behavior
A clear and concise description of what currently happens and what are the steps to reproduce it.
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ jobs:
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 chaos_genius --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 chaos_genius --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# exit-zero treats all errors as warnings.
flake8 chaos_genius --count --exit-zero --statistics
- name: Test with pytest
run: |
pytest
- name: Check diverged migrations
run: |
./scripts/check_diverged_migrations.sh
52 changes: 31 additions & 21 deletions chaos_genius/alerts/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Alerting logic, email/slack formats and other utilities.
Most of the code in this module has extensive type annotation. Please use the Pylance
VS Code extension (or the Pyright equivalent in other editors) along with flake8 when
developing.
"""
import logging
from datetime import date
from typing import List, Tuple
from typing import List, Optional, Tuple

from chaos_genius.alerts.anomaly_alerts import AnomalyAlertController
from chaos_genius.alerts.event_alerts import StaticEventAlertController
Expand All @@ -12,8 +17,8 @@
logger = logging.getLogger()


def check_and_trigger_alert(alert_id):
"""Check the alert and trigger the notification if found
def check_and_trigger_alert(alert_id: int):
"""Check the alert and trigger the notification if found.
Args:
alert_id (int): alert id
Expand All @@ -24,14 +29,16 @@ def check_and_trigger_alert(alert_id):
Returns:
bool: status of the alert trigger
"""
alert_info = Alert.get_by_id(alert_id)
alert_info: Optional[Alert] = Alert.get_by_id(alert_id)
if not alert_info:
raise Exception("Alert doesn't exist")

if not (alert_info.active and alert_info.alert_status):
print("Alert isn't active. Please activate the alert.")
return True

# TODO: extract these values of `alert_type` as an enum
# ref: https://github.com/chaos-genius/chaos_genius/pull/836#discussion_r838077656
if alert_info.alert_type == "Event Alert":

data_source_id = alert_info.data_source
Expand All @@ -43,40 +50,43 @@ def check_and_trigger_alert(alert_id):
elif (
alert_info.alert_type == "KPI Alert" and alert_info.kpi_alert_type == "Anomaly"
):
anomaly_obj = AnomalyAlertController(alert_info.as_dict)
return anomaly_obj.check_and_prepare_alert()
anomaly_obj = AnomalyAlertController(alert_info)
return anomaly_obj.check_and_send_alert()
elif alert_info.alert_type == "KPI Alert" and alert_info.kpi_alert_type == "Static":
static_kpi_alert = StaticKpiAlertController(alert_info.as_dict)
# TODO: is this still needed?
StaticKpiAlertController(alert_info.as_dict)

return True


def trigger_anomaly_alerts_for_kpi(
kpi_obj: Kpi, end_date: date
) -> Tuple[List[int], List[int]]:
kpi_obj: Kpi,
) -> Tuple[List[int], List[Tuple[int, Exception]]]:
"""Triggers anomaly alerts starting from end_date.
Args:
kpi_obj (Kpi): Object of kpi for which alerts are to be triggered
end_date (dateimte.datetime): Datetime object containing the upper bound of anomaly date values
end_date (dateimte.datetime): Datetime object containing the upper bound of
anomaly date values
Returns:
List[int]: List of alert IDs for which alert messages were successfully sent
List[int]: List of alert IDs for which alert failed
List[Tuple[int, Exception]]: List of alert IDs and exceptions for which alert
failed
"""
success_alerts = []
errors = []
alerts = Alert.query.filter(
Alert.kpi == kpi_obj.id, Alert.active == True, Alert.alert_status == True
success_alerts: List[int] = []
errors: List[Tuple[int, Exception]] = []
alerts: List[Alert] = Alert.query.filter(
Alert.kpi == kpi_obj.id,
Alert.active == True, # noqa: E712
Alert.alert_status == True, # noqa: E712
).all()
for alert in alerts:
try:
anomaly_obj = AnomalyAlertController(
alert.as_dict, anomaly_end_date=end_date
)
anomaly_obj.check_and_prepare_alert()
anomaly_obj = AnomalyAlertController(alert)
anomaly_obj.check_and_send_alert()
success_alerts.append(alert.id)
except Exception as e:
logger.error(f"Error running alert for Alert ID: {alert.id}", exc_info=e)
errors.append(alert.id)
errors.append((alert.id, e))
return success_alerts, errors
66 changes: 47 additions & 19 deletions chaos_genius/alerts/alert_channel_creds.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,60 @@
"""Utilities for retrieving channel credentials from config-setting."""
from typing import Tuple

from chaos_genius.controllers.config_controller import get_config_object


def get_creds(name):
return HELPER_FUNC_DICT[name](name)
# TODO: make a new type here to better represent the return value
# ref: https://github.com/chaos-genius/chaos_genius/pull/836#discussion_r838085548
def get_email_creds() -> Tuple[str, int, str, str, str]:
"""Retrieves email channel configuration.
Returns:
A tuple of (host, port, username, password, sender_email)
Raises:
Exception: if email channel was not configured.
"""
# TODO: remove hardcoding of "email" - use a constant or a function
# ref: https://github.com/chaos-genius/chaos_genius/pull/836#discussion_r838110482
config_obj = get_config_object("email")
if not config_obj:
raise Exception("Email alert channel was not configured")

email_config = config_obj.as_dict.get("config_setting")

def get_email_creds(name):
config_obj = get_config_object(name)
if config_obj is None:
return "", "", "", "", ""
if not email_config:
raise Exception("Email alert channel was not configured")

configs = config_obj.as_dict.get("config_setting", {})
return (
configs.get("server", ""),
configs.get("port", ""),
configs.get("username", ""),
configs.get("password", ""),
configs.get("sender_email", ""),
email_config.get("server", ""),
email_config.get("port", 0),
email_config.get("username", ""),
email_config.get("password", ""),
email_config.get("sender_email", ""),
)


def get_slack_creds(name):
config_obj = get_config_object(name)
if config_obj is None:
return ""
def get_slack_creds() -> str:
"""Retrieves slack channel configuration.
Returns:
The slack webhook URL
Raises:
Exception: if slack channel was not configured.
"""
config_obj = get_config_object("slack")
if not config_obj:
raise Exception("Slack alert channel was not configured")

configs = config_obj.as_dict.get("config_setting", {})
return configs.get("webhook_url", "")
configs = config_obj.as_dict.get("config_setting")
if not configs:
raise Exception("Slack alert channel was not configured")

if "webhook_url" not in configs:
raise Exception(
"Slack alert channel configuration is invalid. webhook_url was not found."
)

HELPER_FUNC_DICT = {"email": get_email_creds, "slack": get_slack_creds}
return configs["webhook_url"]
Loading

0 comments on commit c1baf44

Please sign in to comment.