Skip to content

Commit

Permalink
chore: add log levels and e2e testing
Browse files Browse the repository at this point in the history
  • Loading branch information
anaselmhamdi committed Jan 9, 2025
1 parent 13e7e8c commit d30ed16
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 21 deletions.
17 changes: 5 additions & 12 deletions bizon/alerting/alerts.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
from abc import ABC, abstractmethod
from enum import Enum
from typing import Dict, List

from loguru import logger

from bizon.alerting.models import AlertingConfig, AlertMethod


class LogLevel(str, Enum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
CRITICAL = "CRITICAL"
from bizon.alerting.models import AlertingConfig, AlertMethod, LogLevel


class AbstractAlert(ABC):

def __init__(self, type: AlertMethod, config: AlertingConfig):
def __init__(self, type: AlertMethod, config: AlertingConfig, log_levels: List[LogLevel] = [LogLevel.ERROR]):
self.type = type
self.config = config
self.log_levels = log_levels

@abstractmethod
def handler(self, message: Dict) -> None:
pass

def add_handlers(self, levels: List[LogLevel] = [LogLevel.ERROR]) -> None:
def add_handlers(self) -> None:
levels = [level.value for level in self.log_levels]
for level in levels:
logger.add(self.handler, level=level, format="{message}")
11 changes: 10 additions & 1 deletion bizon/alerting/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
from enum import Enum
from typing import Union
from typing import List, Optional, Union

from pydantic import BaseModel

from bizon.alerting.slack.config import SlackConfig


class LogLevel(str, Enum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
CRITICAL = "CRITICAL"


class AlertMethod(str, Enum):
"""Alerting methods"""

Expand All @@ -16,4 +24,5 @@ class AlertingConfig(BaseModel):
"""Alerting configuration model"""

type: AlertMethod
log_levels: Optional[List[LogLevel]] = [LogLevel.ERROR]
config: Union[SlackConfig]
7 changes: 4 additions & 3 deletions bizon/alerting/slack/handler.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import os
from typing import Dict
from typing import Dict, List

import requests
from loguru import logger

from bizon.alerting.alerts import AbstractAlert, AlertMethod
from bizon.alerting.models import LogLevel
from bizon.alerting.slack.config import SlackConfig


class SlackHandler(AbstractAlert):
def __init__(self, config: SlackConfig):
super().__init__(type=AlertMethod.SLACK, config=config)
def __init__(self, config: SlackConfig, log_levels: List[LogLevel] = [LogLevel.ERROR]):
super().__init__(type=AlertMethod.SLACK, config=config, log_levels=log_levels)
self.webhook_url = config.webhook_url

def handler(self, message: Dict) -> None:
Expand Down
8 changes: 5 additions & 3 deletions bizon/engine/runner/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from loguru import logger

from bizon.alerting.alerts import LogLevel
from bizon.alerting.models import AlertMethod
from bizon.cli.utils import parse_from_yaml
from bizon.common.models import BizonConfig, SyncMetadata
Expand Down Expand Up @@ -49,8 +48,11 @@ def __init__(self, config: dict):
if self.bizon_config.alerting.type == AlertMethod.SLACK:
from bizon.alerting.slack.handler import SlackHandler

alert = SlackHandler(webhook_url=self.bizon_config.alerting.config.webhook_url)
alert.add_handlers(levels=[LogLevel.ERROR, LogLevel.WARNING])
alert = SlackHandler(
config=self.bizon_config.alerting.config,
log_levels=self.bizon_config.alerting.log_levels,
)
alert.add_handlers()

@property
def is_running(self) -> bool:
Expand Down
71 changes: 69 additions & 2 deletions tests/alerts/test_slack_alert.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import json
import os
import tempfile
import threading
from http.server import BaseHTTPRequestHandler, HTTPServer
from queue import Queue

import pytest
import yaml
from loguru import logger

from bizon.alerting.slack.config import SlackConfig
from bizon.alerting.slack.handler import SlackHandler
from bizon.engine.engine import RunnerFactory


class DummyWebhookHandler(BaseHTTPRequestHandler):
Expand Down Expand Up @@ -49,8 +54,13 @@ def dummy_webhook_server():
DummyWebhookHandler.payload_queue.queue.clear()


def test_slack_log_handler(dummy_webhook_server):
slack_handler = SlackHandler(SlackConfig(webhook_url="http://localhost:8123"))
@pytest.fixture
def webhook_url():
return "http://localhost:8123"


def test_slack_log_handler(dummy_webhook_server, webhook_url):
slack_handler = SlackHandler(SlackConfig(webhook_url=webhook_url))

slack_handler.add_handlers(levels=["ERROR", "WARNING"])

Expand All @@ -67,3 +77,60 @@ def test_slack_log_handler(dummy_webhook_server):
logger.warning(WARNING_MESSAGE)
warning_payload = DummyWebhookHandler.payload_queue.get(timeout=1)
assert WARNING_MESSAGE in warning_payload


def test_e2e_logger_to_file(dummy_webhook_server, webhook_url):

with tempfile.NamedTemporaryFile(delete=False) as temp:

BIZON_CONFIG_DUMMY_TO_FILE = f"""
name: test_job_3
source:
name: dummy
stream: creatures
authentication:
type: api_key
params:
token: dummy_key
destination:
name: file
config:
filepath: {temp.name}
transforms:
- label: transform_data
python: |
if 'name' in data:
data['name'] = fake_variable # this is purposely wrong to trigger an error
engine:
backend:
type: postgres
config:
database: bizon_test
schema: public
syncCursorInDBEvery: 2
host: {os.environ.get("POSTGRES_HOST", "localhost")}
port: 5432
username: postgres
password: bizon
alerting:
type: slack
config:
webhook_url: {webhook_url}
log_levels:
- ERROR
"""

runner = RunnerFactory.create_from_config_dict(yaml.safe_load(BIZON_CONFIG_DUMMY_TO_FILE))

runner.run()

error_payload = DummyWebhookHandler.payload_queue.get(timeout=1)
assert "Error applying transformation" in error_payload
assert "fake_variable" in error_payload

0 comments on commit d30ed16

Please sign in to comment.