diff --git a/.env.default b/.env.default index 2991382..f28208d 100644 --- a/.env.default +++ b/.env.default @@ -1,3 +1,6 @@ +APP_LIFECYCLE="dev" +SENTRY_ENABLED="False" +SENTRY_DSN="" ADMIN_EMAIL="" ADMIN_FIRST_NAME="" BOT_NAME="" diff --git a/app/commands/submit_task.py b/app/commands/submit_task.py index 6a19ff0..70ef360 100644 --- a/app/commands/submit_task.py +++ b/app/commands/submit_task.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import logging +import sentry_sdk from webex_bot.models.command import Command from webex_bot.models.response import Response, response_from_adaptive_card @@ -113,7 +114,8 @@ class SubmitTaskCommand(Command): Submit(title="Cancel", data={"command_keyword": "exit"}), ], ) - return response_from_adaptive_card(card) + with sentry_sdk.start_transaction(name="submit_task_command"): + return response_from_adaptive_card(card) class SubmitTaskCallback(Command): @@ -147,7 +149,8 @@ class SubmitTaskCallback(Command): ) def execute(self, message, attachment_actions, activity) -> str: - return self.msg + with sentry_sdk.start_transaction(name="submit_task_callback"): + return self.msg class MyTasksCallback(Command): @@ -158,11 +161,13 @@ class MyTasksCallback(Command): self.msg: str = "" def pre_execute(self, message, attachment_actions, activity) -> str: - return "Getting your tasks..." + with sentry_sdk.start_transaction(name="my_tasks_preexec"): + return "Getting your tasks..." def execute(self, message, attachment_actions, activity) -> str | None: sender: str = attachment_actions.inputs.get("sender") result: bool = get_tasks(requestor=sender) - if not result: - return "Failed to get tasks. Please try again." - return + with sentry_sdk.start_transaction(name="my_tasks_exec"): + if not result: + return "Failed to get tasks. Please try again." + return diff --git a/app/main.py b/app/main.py index b84f46a..738d852 100644 --- a/app/main.py +++ b/app/main.py @@ -1,5 +1,8 @@ #!/usr/bin/env python3 +import sentry_sdk +from sentry_sdk.integrations.stdlib import StdlibIntegration + from webex_bot.webex_bot import WebexBot from app.commands.exit import ExitCommand @@ -7,6 +10,16 @@ from app.commands.submit_task import SubmitTaskCommand from app.utils.config import config +if config.sentry_enabled: + apm = sentry_sdk.init( + dsn=config.sentry_dsn, + enable_tracing=True, + environment=config.environment, + integrations=[StdlibIntegration()], + spotlight=True + ) + + def create_bot() -> WebexBot: # Create a Bot Object webex_bot: WebexBot = WebexBot( diff --git a/app/utils/apm.py b/app/utils/apm.py new file mode 100644 index 0000000..3e34fd5 --- /dev/null +++ b/app/utils/apm.py @@ -0,0 +1,16 @@ +import sentry_sdk +from sentry_sdk.integrations.stdlib import StdlibIntegration + +from app.utils.config import config + + +if config.sentry_enabled: + apm = sentry_sdk.init( + dsn=config.sentry_dsn, + enable_tracing=True, + environment=config.environment, + integrations=[StdlibIntegration()], + spotlight=True + ) +else: + apm = None diff --git a/app/utils/config.py b/app/utils/config.py index 27f6e32..a62d235 100644 --- a/app/utils/config.py +++ b/app/utils/config.py @@ -5,12 +5,29 @@ import os class Config: def __init__(self) -> None: + self.__environment: str = os.environ.get("APP_LIFECYCLE", "DEV").upper() self.__bot_name: str = os.environ["BOT_NAME"] self.__webex_token: str = os.environ["WEBEX_API_KEY"] self.__admin_first_name: str = os.environ["ADMIN_FIRST_NAME"] self.__admin_emails: list = os.environ["ADMIN_EMAIL"].split(",") self.__n8n_webhook_url: str = os.environ["N8N_WEBHOOK_URL"] + self.__sentry_dsn: str = os.environ.get("SENTRY_DSN", "") + self.__sentry_enabled: bool = True if (os.environ.get("SENTRY_ENABLED").upper() == "TRUE" and self.__sentry_dsn != "") else False + @property + def environment(self) -> str: + return self.__environment + + @property + def sentry_enabled(self) -> bool: + return self.__sentry_enabled + + @property + def sentry_dsn(self) -> str: + if not self.__sentry_enabled: + return "" + return self.__sentry_dsn + @property def bot_name(self) -> str: return self.__bot_name diff --git a/app/utils/n8n.py b/app/utils/n8n.py index e1d8e31..e9ca514 100644 --- a/app/utils/n8n.py +++ b/app/utils/n8n.py @@ -1,4 +1,5 @@ import requests +import sentry_sdk from app.utils.config import config @@ -16,22 +17,26 @@ def __n8n_post(data: dict) -> bool: def submit_task(summary, description, completion_date, requestor) -> bool: - data: dict = { - "requestor": requestor, - "title": summary, - "description": description, - "completiondate": completion_date, - } - return __n8n_post(data=data) + with sentry_sdk.start_transaction(name="submit_task"): + data: dict = { + "requestor": requestor, + "title": summary, + "description": description, + "completiondate": completion_date, + } + _data = __n8n_post(data=data) + return _data def get_tasks(requestor) -> bool: - headers: dict = {"Content-Type": "application/json"} - resp: requests.Response = requests.get( - url=config.n8n_webhook_url, - headers=headers, - timeout=10, - verify=False, - params={"requestor": requestor}, - ) - return bool(resp.status_code == 200) + with sentry_sdk.start_transaction(name="get_tasks"): + headers: dict = {"Content-Type": "application/json"} + resp: requests.Response = requests.get( + url=config.n8n_webhook_url, + headers=headers, + timeout=10, + verify=False, + params={"requestor": requestor}, + ) + _data = bool(resp.status_code == 200) + return _data diff --git a/requirements.txt b/requirements.txt index ba6e896..f1aee33 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,6 +33,7 @@ python-dotenv==1.0.1 PyYAML==6.0.1 requests==2.31.0 requests-toolbelt==1.0.0 +sentry-sdk==1.45.0 six==1.16.0 toml==0.10.2 tomli==2.0.1 diff --git a/test.sh b/test.sh index b0f95fc..1fcaf08 100755 --- a/test.sh +++ b/test.sh @@ -1,3 +1,3 @@ export $(cat .env | xargs) python -B -m app.main -unset BOT_NAME WEBEX_API_KEY ADMIN_FIRST_NAME ADMIN_EMAIL N8N_WEBHOOK_URL \ No newline at end of file +unset APP_LIFECYCLE SENTRY_ENABLED SENTRY_DSN BOT_NAME WEBEX_API_KEY ADMIN_FIRST_NAME ADMIN_EMAIL N8N_WEBHOOK_URL