Skip to content

Commit

Permalink
Streamlining & Updating
Browse files Browse the repository at this point in the history
WORK IN PROGRESS

Signed-off-by: Bentley Hensel <[email protected]>
  • Loading branch information
TheBoatyMcBoatFace committed Oct 9, 2023
1 parent abbea6f commit 6e3c664
Show file tree
Hide file tree
Showing 15 changed files with 747 additions and 36 deletions.
4 changes: 4 additions & 0 deletions .env-template
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# ------------------------------
# Environmental Variables
# ------------------------------

4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
.nova
.DS_Store
.env
venv
__pycache__
BUILDER.md
logs*
logs*
Binary file added .nova/Artwork
Binary file not shown.
5 changes: 5 additions & 0 deletions .nova/Configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"workspace.art_style" : 1,
"workspace.color" : 12,
"workspace.name" : "Rabbit Run"
}
12 changes: 8 additions & 4 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# __init__.py
# Relative Path: app/__init__.py
from .utils import logger
from .processes import preprocess_data
# app/__init__.py
from .utils import configure_monitoring
from dotenv import load_dotenv


def startup():
load_dotenv()
configure_monitoring()
2 changes: 1 addition & 1 deletion app/database/postgres/connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ def test_connection():



test_connection()
test_connection()
23 changes: 0 additions & 23 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,24 +1 @@
# app/main.py
import time
import sys
import os
from .utils import logger
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from app.processes import execute_axes
from app.database import fetch_unprocessed_rules, mark_axe_rule_as_processed

def yeet_axes():
while True:
rules_to_process = fetch_unprocessed_rules()
if rules_to_process:
# When there are rule_ids to process, process them.
for rule_id in rules_to_process:
execute_axes(rule_id) # Inserts into ClickHouse
mark_axe_rule_as_processed(rule_id) # Marks as processed in Postgres
else:
# When there are no more rule_ids to process, sleep for 10 seconds before checking again.
time.sleep(10)


if __name__ == "__main__":
yeet_axes()
5 changes: 2 additions & 3 deletions app/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# __init__.py
# Relative Path: app/utils/__init__.py
from .logger import logger
# app/utils/__init__.py
from .monitoring import which_extras as configure_monitoring
18 changes: 18 additions & 0 deletions app/utils/monitoring/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# app/utils/monitoring/__init__.py
import os
from .sentry import configure_sentry
from .pyroscope import configure_pyroscope
from .logging import logger

def which_extras():
# Check if SENTRY_DSN environment variable has a value
if os.getenv("SENTRY_DSN"):
configure_sentry()
logger.info('Sentry Configured')

# Check if PYROSCOPE_API_KEY environment variable has a value
if os.getenv("PYROSCOPE_API_KEY"):
configure_pyroscope()
logger.info('Pyroscope Configured')


89 changes: 89 additions & 0 deletions app/utils/monitoring/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# app/utils/monitoring/logger.py
import logging
import os
import time
from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
import json

# Logger Name and Level
LOGGER_NAME = "LoggyMcLogFace"
LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO").upper()
LOG_VERBOSE = True if LOG_LEVEL == "DEBUG" else os.environ.get("LOG_VERBOSE", "False").lower() == "true"

if LOG_VERBOSE:
FMT_STREAM = "%(asctime)s.%(msecs)03d %(levelname)-8s [%(filename)s:%(funcName)s:%(lineno)d] %(message)s"
datefmt = '%Y-%m-%d %H:%M:%S'
else:
FMT_STREAM = " %(levelname)-8s %(message)s"
datefmt = None

# Set up logger:
logger = logging.getLogger(LOGGER_NAME)
logger.setLevel(LOG_LEVEL)

# Create the logs directory if it doesn't exist
if not os.path.exists("logs"):
os.makedirs("logs")

# Handlers
filename = f"logs/{LOGGER_NAME}-{time.strftime('%Y-%m-%d')}.log"

# Timed Rotating File Handler
timed_file_handler = TimedRotatingFileHandler(filename=filename, when="midnight", interval=1, backupCount=30)
timed_file_handler.setLevel(LOG_LEVEL)

# Size-based Rotating File Handler
size_file_handler = RotatingFileHandler(filename=filename, maxBytes=5*1024*1024, backupCount=3) # 5MB per file
size_file_handler.setLevel(LOG_LEVEL)

shell_handler = logging.StreamHandler()
shell_handler.setLevel(LOG_LEVEL)

# Formatters
shell_formatter = logging.Formatter(FMT_STREAM, datefmt=datefmt)
json_formatter = logging.Formatter(json.dumps({
"time": "%(asctime)s.%(msecs)03d",
"level": "%(levelname)-8s",
"file": "%(filename)s",
"function": "%(funcName)s",
"line": "%(lineno)d",
"message": "%(message)s"
}))
size_file_handler.setFormatter(json_formatter)
timed_file_handler.setFormatter(json_formatter)
shell_handler.setFormatter(shell_formatter)

# Add handlers to logger
logger.addHandler(shell_handler)
logger.addHandler(timed_file_handler)
logger.addHandler(size_file_handler)

def configure_logger():
"""
Reconfigure the logger.
This function reconfigures the logger with the predefined settings.
"""
global logger
logger = logging.getLogger(LOGGER_NAME)

def log_exception(exc_type, exc_value, exc_traceback):
"""
Logs an exception with its traceback.
"""
logger.error(
"Uncaught exception",
exc_info=(exc_type, exc_value, exc_traceback)
)

# Log statements for testing purposes
if __name__ == "__main__":
import sys
sys.excepthook = log_exception

logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")

35 changes: 35 additions & 0 deletions app/utils/monitoring/pyroscope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# app/utils/monitoring/pyroscope.py
import os
import socket
import platform
from .logging import logger
import pyroscope

def configure_pyroscope():
logger.info('Configuring Pyroscope')
host = socket.gethostname()
platform_info = platform.platform()
python_version = platform.python_version()
host_os = platform.system()
host_os_release = platform.release()
host_os_version = platform.version()
host_machine_type = platform.machine()
host_processor = platform.processor()
python_implementation = platform.python_implementation()
python_compiler = platform.python_compiler()
python_build = platform.python_build()
logger.debug('Pyroscope Vars Imported...')

pyroscope.configure(
application_name=os.getenv("PYROSCOPE_APPLICATION_NAME"),
server_address=os.getenv("PYROSCOPE_SERVER"),
auth_token=os.getenv("PYROSCOPE_API_KEY"),
)
logger.info('Pyroscope Configured')


def traces_sampler(sampling_context):
# Customize your sampling logic here if needed
# return a number between 0 and 1 or a boolean
return 1.0

79 changes: 79 additions & 0 deletions app/utils/monitoring/sentry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# app/utils/monitoring/sentry.py
import os
from .logging import logger, LOG_LEVEL
import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
from sentry_sdk.integrations.excepthook import ExcepthookIntegration
from sentry_sdk.integrations.modules import ModulesIntegration
from sentry_sdk.integrations.threading import ThreadingIntegration


def configure_sentry():
"""Configure Sentry with custom sampling logic."""
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
integrations=[
LoggingIntegration(level=LOG_LEVEL),
ExcepthookIntegration(always_run=True),
ModulesIntegration(),
ThreadingIntegration(propagate_hub=True),
],
traces_sample_rate=traces_sampler(),
profiles_sample_rate=profiles_sampler(),
)


def traces_sampler(sampling_context=None):
"""Customize trace sampling logic if needed.
Args:
sampling_context (dict, optional): Context for the sampling decision.
Returns:
float: Sampling rate between 0 and 1.
"""
default_sampling_rate = 1.0

if sampling_context is None:
sampling_rate = default_sampling_rate
elif sampling_context.get("food") == "Tacos":
sampling_rate = 0.5
elif sampling_context.get("food") == "Pears":
sampling_rate = 0.5
else:
sampling_rate = default_sampling_rate

logger.info(f'Traces Sampling Rate: %s', sampling_rate)
return sampling_rate


def profiles_sampler(sampling_context=None):
"""Customize profile sampling logic if needed.
Args:
sampling_context (dict, optional): Context for the sampling decision.
Returns:
float: Sampling rate between 0 and 1.
"""
default_sampling_rate = 1.0

if sampling_context is None:
sampling_rate = default_sampling_rate
elif sampling_context.get("food") == "Tacos":
sampling_rate = 0.5
elif sampling_context.get("food") == "Pears":
sampling_rate = 0.5
else:
sampling_rate = default_sampling_rate

logger.info(f'Profile Sampling Rate: %s', sampling_rate)
return sampling_rate


# Test
if __name__ == "__main__":
try:
division_by_zero = 1 / 0
except ZeroDivisionError:
sentry_sdk.capture_exception()
Loading

0 comments on commit 6e3c664

Please sign in to comment.