Skip to content

Commit

Permalink
Merge pull request #3 from akimrx/fix-workdays-metrics
Browse files Browse the repository at this point in the history
fix(metrics): fixed bug with workdays metrics, replaced lib
  • Loading branch information
akimrx authored Jul 2, 2023
2 parents 220c378 + c643471 commit 472fe91
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 15 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ run_migration
| `EXPORTER_CLICKHOUSE_DATABASE` | ❌ | `agile` | Database for exporter CH tables |
| `EXPORTER_CLICKHOUSE_ISSUES_TABLE` | ❌ | `issues` | Table when store issues metadata |
| `EXPORTER_CLICKHOUSE_ISSUE_METRICS_TABLE` | ❌ | `issue_metrics` | Table when store issue metrics |
| `EXPORTER_WORKHOURS_START` | ❌ | 9 | The beginning of working hours for calculating business hour metrics |
| `EXPORTER_WORKHOURS_END` | ❌ | 22 | The end of working hours for calculating business hour metrics |
# Monitoring
Expand Down
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
yandex_tracker_client==2.3
clickhouse_driver==0.2.*
datadog==0.44.*
apscheduler==3.9.*
requests==2.27.*
pandas==1.3.*
numpy==1.21.*
businesstime==0.3.*
businesstimedelta==1.0.*
holidays==0.14.*
sentry-sdk==1.6.*
python-dotenv==0.20.*
4 changes: 2 additions & 2 deletions tracker_exporter/__version__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# pylint: disable=C0103,W0622
version = "0.1.17"
version = "0.1.18"
url = "https://github.com/akimrx/yandex-tracker-exporter"
download_url = "https://pypi.org/project/tracker-exporter/"
appname = "yandex_tracker_exporter"
description = "Yandex.Tracker issue metrics exporter"
author = "Akim Faskhutdinov"
author_email = "[email protected]"
author_email = "[email protected]"
license = "MIT"
10 changes: 7 additions & 3 deletions tracker_exporter/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
UPLOAD_TO_STORAGE = os.environ.get("EXPORTER_ENABLE_UPLOAD", "false").lower() in ("true", "yes")

# Business days settings
BUSINESS_HOURS_START = dt.time(9)
BUSINESS_HOURS_END = dt.time(22)
WEEKENDS = (5, 6,) # Monday is 0, Sunday is 6
WORKDAYS = [0, 1, 2, 3, 4] # From Monday to Friday
try:
BUSINESS_HOURS_START = dt.time(int(os.environ.get("EXPORTER_WORKHOURS_START", "9")))
BUSINESS_HOURS_END = dt.time(int(os.environ.get("EXPORTER_WORKHOURS_END", "22")))
except (ValueError, TypeError):
BUSINESS_HOURS_START = dt.time(9)
BUSINESS_HOURS_END = dt.time(22)

# Monitoring settings
MONITORING_ENABLED = os.environ.get("EXPORTER_MONITORING_ENABLED", "false").lower() in ("true", "yes")
Expand Down
4 changes: 2 additions & 2 deletions tracker_exporter/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class Exporter:
# TODO: configure class instance
# TODO: parse migration from sprint to sprint by changelog (field changed),
# by default exported only last sprint (tracker logic)
def __init__(self):
self.clickhouse = ClickhouseClient(
def __init__(self, clickhouse_client: ClickhouseClient = None):
self.clickhouse = clickhouse_client or ClickhouseClient(
host=CLICKHOUSE_HOST,
port=CLICKHOUSE_HTTP_PORT,
user=CLICKHOUSE_USER,
Expand Down
5 changes: 4 additions & 1 deletion tracker_exporter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
help="Path to .env file"
)
args = parser.parse_args()
load_dotenv(args.env_file)
warnings.filterwarnings("ignore")

if args.env_file:
load_dotenv(args.env_file)


# pylint: disable=C0413
from .errors import ExportError
from .services.monitoring import DogStatsdClient, sentry_events_filter
Expand Down
21 changes: 16 additions & 5 deletions tracker_exporter/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

import holidays
import pandas as pd
import businesstimedelta

from businesstime import BusinessTime
from tracker_exporter.models.enums import TimeDeltaOut
from tracker_exporter.defaults import (
NOT_NULLABLE_FIELDS,
WEEKENDS,
WORKDAYS,
BUSINESS_HOURS_START,
BUSINESS_HOURS_END,
TRACKER_DEFAULT_DATETIME_FORMAT
Expand All @@ -40,26 +40,37 @@ def get_timedelta(end_time: datetime,
def calculate_time_spent(start_date: datetime,
end_date: datetime,
busdays_only: bool = False,
weekends: Tuple[int] = WEEKENDS,
workdays: list = WORKDAYS,
business_hours: Tuple = (BUSINESS_HOURS_START, BUSINESS_HOURS_END,)) -> int:
"""
Calculate timedelta between dates with business days support.
Weekdays: Monday is 0, Sunday is 6, so weekends (5, 6) mean (Sat, Sun).
Returns: seconds
"""
if not isinstance(start_date, datetime):
start_date = pd.to_datetime(start_date)
if not isinstance(end_date, datetime):
end_date = pd.to_datetime(end_date)

holiday_rules = businesstimedelta.HolidayRule(holidays.RU())
workday_rules = businesstimedelta.WorkDayRule(
start_time=business_hours[0],
end_time=business_hours[1],
working_days=workdays)


if busdays_only:
bt = BusinessTime(business_hours=business_hours, weekends=weekends, holidays=holidays.RU()) # pylint: disable=C0103
result = bt.businesstimedelta(start_date, end_date).total_seconds()
logger.debug(f"Calculating workhours. Business hours: {business_hours}. {start_date}, {end_date}")
bt = businesstimedelta.Rules([workday_rules, holiday_rules])
result = bt.difference(start_date, end_date).timedelta.total_seconds()
else:
logger.debug(f"Calculating regular hours")
result = (end_date - start_date).total_seconds()

return abs(int(result))



def fix_null_dates(data: dict) -> dict:
to_remove = []

Expand Down

0 comments on commit 472fe91

Please sign in to comment.