237 lines
7.4 KiB
Python
237 lines
7.4 KiB
Python
from tracemalloc import start
|
|
from decouple import config
|
|
import sys
|
|
import yaml
|
|
import datetime
|
|
import time
|
|
import pandas as pd
|
|
#import requests
|
|
#import openpyxl
|
|
import argparse
|
|
import warnings
|
|
import os
|
|
import re
|
|
#import glob
|
|
|
|
import dynatraceAPI
|
|
from pagination import Pagionation
|
|
|
|
import types
|
|
import SLO
|
|
from patterns.Pattern1 import Pattern1, Pattern2, Pattern3
|
|
|
|
|
|
warnings.filterwarnings("ignore")
|
|
|
|
|
|
patterns=[Pattern1(), Pattern2(), Pattern3()]
|
|
|
|
def get_request(url, headers):
|
|
try:
|
|
response = requests.get(url, headers=headers)
|
|
response.raise_for_status()
|
|
except requests.exceptions.HTTPError as errh:
|
|
return "An Http Error occurred:" + repr(errh)
|
|
except requests.exceptions.ConnectionError as errc:
|
|
return "An Error Connecting to the API occurred:" + repr(errc)
|
|
except requests.exceptions.Timeout as errt:
|
|
return "A Timeout Error occurred:" + repr(errt)
|
|
except requests.exceptions.RequestException as err:
|
|
return "An Unknown Error occurred" + repr(err)
|
|
|
|
return response
|
|
|
|
def getSLO(DTAPIToken, DTENV):
|
|
# DTENV = base url
|
|
# DTAPIToken = sec token
|
|
dtclient = dynatraceAPI.Dynatrace(DTENV, DTAPIToken)
|
|
my_params_report = {'pageSize': 25}
|
|
# gets all slos and filter later
|
|
api_url_report = "/api/v2/slo"
|
|
pages = dtclient.returnPageination(api_url_report, my_params_report, "slo")
|
|
#only_wanted = [x for x in pages.elements if str.lower(selector) in str.lower(x['description'])]
|
|
df = pd.DataFrame(pages.elements)
|
|
return df
|
|
|
|
|
|
|
|
|
|
def init_argparse():
|
|
parser = argparse.ArgumentParser(
|
|
usage="%(prog)s [--fromDate] [toDate] or [preSelect]",
|
|
description="gather SLO in daily slices for given Timeframe"
|
|
)
|
|
parser.add_argument(
|
|
"-f","--fromDate",
|
|
help = "YYYY-mm-dd e.g. 2022-01-01"
|
|
)
|
|
parser.add_argument(
|
|
"-t","--toDate",
|
|
help = "YYYY-mm-dd e.g. 2022-01-31"
|
|
)
|
|
parser.add_argument(
|
|
"-p","--preSelect",
|
|
help = "day | week | month - gathers the data for the last full day, week or month"
|
|
)
|
|
parser.add_argument(
|
|
"-s","--slices",
|
|
help = "h | d | t | y - writes the slices hourly, daily, total or year to date into ecxel. given in any order"
|
|
)
|
|
|
|
|
|
return parser
|
|
|
|
def check_inputs(args):
|
|
'''
|
|
This functions is the single point of true for arguments. If new arguments are added they need to be added in here. Returns from and to date.
|
|
'''
|
|
if args.preSelect and (args.fromDate or args.toDate):
|
|
print("--preSelect must not be used in conjuntion with --fromDate and/or --toDate")
|
|
sys.exit()
|
|
|
|
elif args.fromDate and not args.toDate:
|
|
print("--fromDate only in conjunction with --toDate")
|
|
sys.exit()
|
|
|
|
elif args.toDate and not args.fromDate:
|
|
print("--toDate only in conjunction with --fromDate")
|
|
sys.exit()
|
|
|
|
elif args.toDate and args.fromDate and not args.preSelect:
|
|
try:
|
|
#fromDate = datetime.date.fromisoformat(args.fromDate)
|
|
fromDate = datetime.datetime.strptime(args.fromDate, "%Y-%m-%d")
|
|
|
|
#toDate = datetime.date.fromisoformat(args.toDate)
|
|
toDate = datetime.datetime.strptime(args.toDate, "%Y-%m-%d")
|
|
except Exception as e:
|
|
print("Progam closed: " + str(e))
|
|
sys.exit()
|
|
|
|
if toDate < fromDate:
|
|
print("--toDate can't be older than --fromDate")
|
|
sys.exit()
|
|
|
|
if toDate > datetime.date.today() or fromDate > datetime.date.today():
|
|
print("--toDate or --fromDate can't be in the future")
|
|
sys.exit()
|
|
|
|
elif args.preSelect and not args.fromDate and not args.toDate:
|
|
|
|
date = datetime.date.today()
|
|
|
|
if args.preSelect == "week":
|
|
fromDate, toDate = previous_week_range(date)
|
|
elif args.preSelect == "month":
|
|
fromDate, toDate = previous_month_range(date)
|
|
elif args.preSelect == "day":
|
|
fromDate, toDate = previous_day_range(date)
|
|
else:
|
|
print("--preSelect must be week or month")
|
|
sys.exit()
|
|
else:
|
|
print("Invalid arguments, please use --help")
|
|
sys.exit()
|
|
if args.slices == None:
|
|
print("-s or --slices must not be null and needs at least one letter of h d t or y, lower- or uppercase.")
|
|
sys.exit()
|
|
elif sum([1 if one_inp in str.lower(args.slices) else 0 for one_inp in ['h','d','t','y'] ]) == 0:
|
|
print("-s or --slices must has at least one letter of h d t or y, lower- or uppercase.")
|
|
sys.exit()
|
|
return fromDate, toDate
|
|
|
|
|
|
|
|
|
|
def write_slo_to_excel(args, fromDate, hourlyall, dailyall, totalall, ytd):
|
|
touchpoints = ['Vehicle' , 'Mobile']
|
|
if args.preSelect == 'day':
|
|
today = datetime.date.today()
|
|
yesterday = today - datetime.timedelta(days = 1)
|
|
fileName = "./QM_Report_"+ str(yesterday) +".xlsx"
|
|
else:
|
|
fileName = "./QM_Report_" + str(fromDate.isocalendar()[1]) + ".xlsx"
|
|
|
|
writer = pd.ExcelWriter(fileName)
|
|
|
|
if not totalall.empty and 't' in str.lower(args.slices):
|
|
totalall = totalall[totalall['Touchpoint'].isin(touchpoints)]
|
|
totalall.to_excel(writer, sheet_name='total')
|
|
|
|
if not dailyall.empty and 'd' in str.lower(args.slices):
|
|
dailyall = dailyall[dailyall['Touchpoint'].isin(touchpoints)]
|
|
dailyall.to_excel(writer, sheet_name='daily')
|
|
|
|
if not hourlyall.empty and 'h' in str.lower(args.slices):
|
|
hourlyall = hourlyall[hourlyall['Touchpoint'].isin(touchpoints)]
|
|
hourlyall.to_excel(writer, sheet_name='hourly')
|
|
|
|
if not ytd.empty and 'y' in str.lower(args.slices):
|
|
ytd = ytd[ytd['Touchpoint'].isin(touchpoints)]
|
|
ytd.to_excel(writer, sheet_name='YTD')
|
|
|
|
writer.save()
|
|
writer.close()
|
|
|
|
|
|
|
|
def parseAndCreateSLOObject(row):
|
|
|
|
|
|
normalizedMetric=normalize(row['metricExpression'])
|
|
tmp_SLO=SLO.SLO(row["name"], normalizedMetric, None)
|
|
|
|
for p in patterns:
|
|
services, methods=p.parseServicesAndMethods(normalizedMetric)
|
|
|
|
if methods != None and len(methods) > 0:
|
|
tmp_SLO.keyRequestGroup.append({"services":services,"methods":methods})
|
|
break
|
|
|
|
|
|
return tmp_SLO
|
|
|
|
|
|
|
|
def normalize(x):
|
|
tmp=x.replace("~","")
|
|
tmp=tmp.replace("\n","")
|
|
#tmp=tmp.replace("\"/","\"")
|
|
tmp=tmp.replace("\"/","")
|
|
#tmp=tmp.replace("/\"","\"")
|
|
tmp=tmp.replace("/\"","")
|
|
tmp=tmp.replace("\"","")
|
|
return tmp
|
|
|
|
|
|
def main(slo_path):
|
|
|
|
with open('./environment.yaml') as file:
|
|
env_doc = yaml.safe_load(file)
|
|
|
|
slos=[]
|
|
|
|
#iterate through all environments
|
|
for item, doc in env_doc.items():
|
|
token = dict(doc[2])
|
|
url = dict(doc[1])
|
|
|
|
if(config(token.get('env-token-name')) != ""):
|
|
print("Gather data, hold on a minute")
|
|
DTTOKEN = config(token.get('env-token-name'))
|
|
DTURL = url.get('env-url')
|
|
|
|
slosF=getSLO(DTTOKEN, DTURL)
|
|
for index, row in slosF.iterrows():
|
|
#if row['id'] == "75165058-75c6-385e-a78e-b6ea3457f87d":
|
|
slos.append(parseAndCreateSLOObject(row))
|
|
print("huhu")
|
|
|
|
for slo in slos:
|
|
slo.checkKeyRequetsExists(DTURL, DTTOKEN)
|
|
|
|
x=0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main('./slo_parameter.yaml') |