mobile config

custom-service-JONYR
qxz15oi 2021-05-07 15:32:35 +02:00
parent 36dd856a48
commit 1339aa41e3
17 changed files with 790 additions and 9 deletions

View File

@ -0,0 +1,54 @@
### Provider Breakdown Configuration
- Dynatrace automatically recognizes more than 1,000 3rd-party content providers, including Google, Amazon, Twitter, and LinkedIn.
Typical 3rd-party content includes Facebook and Twitter widgets, gravatars, and similar resources.
It's worth monitoring this type of content to know exactly how it affects your applications and to understand if such content is the root cause of any page slow-downs.
- This extesions allows you to set up rules that define how your applications' downloaded content resources (images, CSS, 3rd party widgets, and more) are displayed
and categorized for analysis.
- This extension allows you to keep the configuration consistent accross all tenants
#### Download configuration
1. Configure *config.ini* file:
```
downloadConfig = 1
updateConfig = 0
```
2. Run the script:
```
python providerBreakdown.py
```
3. The configuration will appear under */data/<tenant>/contentResources/contentResources.json*
#### Create configuration
*Use case: A team wants to create a new provider breakdown rule*
1. Configure *config.ini* file:
```
downloadConfig = 0
updateConfig = 1
```
2. Edit the file */data/<tenant>/contentResources/contentResources.json* adding the desired rule. For example:
```
{
"resourceName": "OneLogin (Prod)",
"resourceType": "FIRST_PARTY_RESOURCES",
"brandIconUrl": "https://empty",
"domainNamePatterns": [
"customer.bmwgroup.com"
]
}
```
3. Run the script:
```
python providerBreakdown.py
```
#### Delete configuration
1. Same process as before:
- access the JSON
- delete the target rule
- run the update

View File

@ -0,0 +1,14 @@
[ENDPOINT]
endpoint = /api/config/v1/applications/mobile
[ACTION]
downloadConfig = 1
updateConfig = 0
[TENANTS]
#tenant1 = https://dynatracemgd-cn.bmwgroup.net/e/b921f1b9-c00e-4031-b9d1-f5a0d530757b CN_PreProd_TOKEN
#tenant2 = https://dynatracemgd-cn.bmwgroup.net/e/ab88c03b-b7fc-45f0-9115-9e9ecc0ced35 CN_Prod_TOKEN
#tenant3 = https://xxu26128.live.dynatrace.com xxu26128_TOKEN
#tenant4 = https://wgv50241.live.dynatrace.com wgv50241_TOKEN
tenant5 = https://qqk70169.live.dynatrace.com qqk70169_TOKEN
#tenant6 = https://onb44935.live.dynatrace.com onb44935_TOKEN

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-1FD55938A63C43BA",
"name": "Mobile 2.0 MINI - ROW DST INT (iOS & Android)",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "1fd55938-a63c-43ba-8413-de3dfe92b497",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 3000,
"frustratingThreshold": 12000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": true,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,102 @@
{
"sessionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
],
"userActionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
]
}

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-21A9592CADC54C37",
"name": "Mobile 2.0 BMW - ROW DST INT (iOS & Android)",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "21a9592c-adc5-4c37-9192-b9a79fff6108",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 60000,
"frustratingThreshold": 60000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": false,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,102 @@
{
"sessionProperties": [
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_isLcsSupported"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headUnit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_puStep"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsUnit"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_iStep"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_driveTrain"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiVersion"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodyType"
}
],
"userActionProperties": [
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_isLcsSupported"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headUnit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_puStep"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsUnit"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_iStep"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_driveTrain"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiVersion"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodyType"
}
]
}

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-80051BA2B2484DEC",
"name": "Mobile 2 - DevOps Sandbox",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "80051ba2-b248-4dec-b8ae-7d82cc01e801",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 3000,
"frustratingThreshold": 12000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": false,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-B9A52D06BCC64906",
"name": "Mobile 2.0 Toyota - ROW DST INT (iOS & Android)",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "b9a52d06-bcc6-4906-8f2f-b2eb997cafd2",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 3000,
"frustratingThreshold": 12000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": true,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-BD5E6D01E0E64555",
"name": "Mobile 2.0 MINI - KR DST INT (iOS & Android)",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "bd5e6d01-e0e6-4555-8786-62292fb34526",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 3000,
"frustratingThreshold": 12000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": true,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,102 @@
{
"sessionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
],
"userActionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
]
}

View File

@ -0,0 +1,16 @@
{
"identifier": "MOBILE_APPLICATION-EC17924E243B4995",
"name": "Mobile 2.0 BMW - KR DST INT (iOS & Android)",
"applicationType": "MOBILE_APPLICATION",
"applicationId": "ec17924e-243b-4995-a992-fae1a05955ad",
"costControlUserSessionPercentage": 100,
"apdexSettings": {
"toleratedThreshold": 3000,
"frustratingThreshold": 12000,
"frustratedOnError": true
},
"optInModeEnabled": true,
"sessionReplayEnabled": true,
"sessionReplayOnCrashEnabled": true,
"beaconEndpointType": "CLUSTER_ACTIVE_GATE"
}

View File

@ -0,0 +1,102 @@
{
"sessionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
],
"userActionProperties": [
{
"key": "vehicle_year",
"displayName": "vehicle_year"
},
{
"key": "vehicle_telematicsunit",
"displayName": "vehicle_telematicsunit"
},
{
"key": "vehicle_pustep",
"displayName": "vehicle_pustep"
},
{
"key": "vehicle_model",
"displayName": "vehicle_model"
},
{
"key": "vehicle_istep",
"displayName": "vehicle_istep"
},
{
"key": "vehicle_islcssupported",
"displayName": "vehicle_islcssupported"
},
{
"key": "vehicle_hmiversion",
"displayName": "vehicle_hmiversion"
},
{
"key": "vehicle_headunit",
"displayName": "vehicle_headunit"
},
{
"key": "vehicle_drivetrain",
"displayName": "vehicle_drivetrain"
},
{
"key": "vehicle_brand",
"displayName": "vehicle_brand"
},
{
"key": "vehicle_bodytype",
"displayName": "vehicle_bodytype"
},
{
"key": "app_version_build",
"displayName": "app_version_build"
}
]
}

View File

@ -0,0 +1,199 @@
import os, requests, time, json, sys, logging, configparser
from datetime import datetime, timedelta
from http.cookies import SimpleCookie
from pathlib import Path
def checkAPIlimit():
global number_of_calls
print("API calls: ", str(number_of_calls+1))
if number_of_calls == 59:
print("Sleeping")
time.sleep(60)
number_of_calls=0
def saveValues():
YOUR_DT_API_URL = tenant_info.split(" ")[0].rstrip('\n')
YOUR_DT_API_TOKEN = tenant_info.split(" ")[1].rstrip('\n')
return YOUR_DT_API_URL, YOUR_DT_API_TOKEN
def getList():
print('Iterate through list? y/n')
iterate = input()
if iterate == 'y':
print('Enter the key of the object:')
jsonKey = input()
else:
jsonKey = None
return iterate, jsonKey
def download():
#Create /data folder
endpointLast = endpoint
if "/" in endpoint:
endpointLast = endpoint.split("/")[-1]
directory="data/"+env_id+"/"+endpointLast
Path(directory).mkdir(parents=True, exist_ok=True)
print(''.join(YOUR_DT_API_URL) + endpoint)
r = requests.get(''.join(YOUR_DT_API_URL) + endpoint, headers=headers, cookies=dict(cookies), verify=False);
data_json = json.loads(r.text)
iterate = False
for key in data_json.keys():
if type(data_json[key]) is list:
if "id" in data_json[key][0]:
iterate = True
iterative_key = key
if iterate == True:
i=0
while i<len(data_json[iterative_key]):
# mobile application id
id_rule = data_json[iterative_key][i]['id']
# Get mobile application config
rule = requests.get(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule, headers=headers, cookies=dict(cookies), verify=False);
mobile_directory="data/"+env_id+"/"+endpointLast+"/"+id_rule
Path(mobile_directory).mkdir(parents=True, exist_ok=True)
# Save mobile application config
f = open(mobile_directory+"/"+id_rule+".json", "w")
json_data = json.loads(rule.text)
json_formatted_str = json.dumps(json_data, indent=2)
f.write(json_formatted_str)
f.close()
kua_directory="data/"+env_id+"/"+endpointLast+"/"+id_rule+"/userActionAndSessionProperties"
Path(kua_directory).mkdir(parents=True, exist_ok=True)
# Get userActionAndSessionProperties
kua = requests.get(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule+"/userActionAndSessionProperties", headers=headers, cookies=dict(cookies), verify=False);
# Save mobile application config
f = open(kua_directory+"/userActionAndSessionProperties.json", "w")
json_data = json.loads(kua.text)
json_formatted_str = json.dumps(json_data, indent=2)
f.write(json_formatted_str)
f.close()
usp_directory="data/"+env_id+"/"+endpointLast+"/"+id_rule+"/userActionAndSessionProperties"
Path(usp_directory).mkdir(parents=True, exist_ok=True)
# Get userActionAndSessionProperties
kua = requests.get(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule+"/userActionAndSessionProperties", headers=headers, cookies=dict(cookies), verify=False);
# Save mobile application config
f = open(usp_directory+"/userActionAndSessionProperties.json", "w")
json_data = json.loads(kua.text)
json_formatted_str = json.dumps(json_data, indent=2)
f.write(json_formatted_str)
f.close()
i+=1
else:
f = open(directory+"/"+endpointLast+".json", "w")
json_data = json.loads(r.text)
json_formatted_str = json.dumps(json_data, indent=2)
f.write(json_formatted_str)
def update():
endpointLast = endpoint
if "/" in endpoint:
endpointLast = endpoint.split("/")[-1]
#Get list of mobile app ids
r = requests.get(''.join(YOUR_DT_API_URL) + endpoint, headers=headers, cookies=dict(cookies), verify=False);
data_json = json.loads(r.text)
# Obtain iterative_key
for key in data_json.keys():
if type(data_json[key]) is list:
if "id" in data_json[key][0]:
iterative_key = key
i=0
while i<len(data_json[iterative_key]):
# Create directory for each application
id_rule = data_json[iterative_key][i]['id']
directory = "data/"+env_id+"/"+endpointLast+"/"+id_rule
# Update config mobile app
filename=id_rule+".json"
with open(os.path.join(directory, filename), 'r+') as myfile:
data=myfile.read()
r = requests.put(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule, data, headers=headers, cookies=dict(cookies), verify=False)
# Update config mobile app userActionAndSessionProperties
if os.path.exists(directory+"/userActionAndSessionProperties"):
with open(os.path.join(directory+"/userActionAndSessionProperties", "userActionAndSessionProperties.json"), 'r+') as myfile:
data=myfile.read()
r = requests.put(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule+"/userActionAndSessionProperties", data, headers=headers, cookies=dict(cookies), verify=False)
if os.path.exists(directory+"/keyUserActions"):
# Update config mobile app keyUserActions
with open(os.path.join(directory+"/keyUserActions", "keyUserActions.json"), 'r+') as myfile:
data=myfile.read()
r = requests.put(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule+"/keyUserActions", data, headers=headers, cookies=dict(cookies), verify=False)
i+=1
if __name__ == '__main__':
number_of_calls = 0
YOUR_DT_API_URL = ''
YOUR_DT_API_TOKEN = ''
cookies = {"null":"null"}
user = "null"
config = configparser.ConfigParser()
config.read('config.ini')
updateConfig = config['ACTION']['updateConfig']
downloadConfig = config['ACTION']['downloadConfig']
endpoint = config['ENDPOINT']['endpoint']
endpoint = endpoint.rstrip("\n")
for (key, val) in config.items('TENANTS'):
tenant_info = val
extracted_tenant_info = saveValues()
YOUR_DT_API_URL = extracted_tenant_info[0]
TOKEN = extracted_tenant_info[1]
YOUR_DT_API_TOKEN = os.getenv(TOKEN)
#Build the header and cookie
headers={}
headers["Authorization"] = "Api-Token "+YOUR_DT_API_TOKEN
headers["Content-Type"] = "application/json"
#Generate env_id
if "/e/" in YOUR_DT_API_URL:
env_id = YOUR_DT_API_URL.split("/e/")[1]
else:
env_id = YOUR_DT_API_URL.split("//")[1]
#Create /data folder
if not os.path.exists('data/'):
os.mkdir('data/')
#Create tenant folder
path = "data/"+env_id
if not os.path.exists(path):
os.mkdir(path)
print("\n")
if downloadConfig=='1':
print("Downloading rules of "+ env_id)
download()
if updateConfig=='1':
print("Updating rules of "+ env_id)
update()
print("\n")

View File

@ -45,11 +45,12 @@ def download():
if type(data_json[key]) is list:
if "id" in data_json[key][0]:
iterate = True
iterative_key = key
if iterate == True:
i=0
while i<len(data_json['values']):
id_rule = data_json['values'][i]['id']
while i<len(data_json[iterative_key]):
id_rule = data_json[iterative_key][i]['id']
rule = requests.get(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule, headers=headers, cookies=dict(cookies), verify=False);
f = open(directory+"/"+id_rule+".json", "w")
json_data = json.loads(rule.text)

View File

@ -40,9 +40,9 @@ def delete():
data_json = json.loads(r.text)
i=0
while i<len(data_json['values']):
while i<len(data_json[iterative_key]):
delete_file = True
id_rule = data_json['values'][i]['id']
id_rule = data_json[iterative_key][i]['id']
#Match id with file name
for filename in os.listdir(directory):
@ -51,10 +51,10 @@ def delete():
if delete_file==True:
#Confirm deletion
question = input('Would you like to delete '+ data_json['values'][i]['id']+"?\n")
question = input('Would you like to delete '+ data_json[iterative_key][i]['id']+"?\n")
if question.lower() == 'yes' or question.lower() == 'y':
print("Deleting "+data_json['values'][i]['id'])
r = requests.delete(''.join(YOUR_DT_API_URL) + endpoint+"/"+data_json['values'][i]['id'], headers=headers, cookies=dict(cookies), verify=False);
print("Deleting "+data_json[iterative_key][i]['id'])
r = requests.delete(''.join(YOUR_DT_API_URL) + endpoint+"/"+data_json[iterative_key][i]['id'], headers=headers, cookies=dict(cookies), verify=False);
print(r)
else:
print ("Deletion skipped")
@ -77,11 +77,12 @@ def download():
if type(data_json[key]) is list:
if "id" in data_json[key][0]:
iterate = True
iterative_key = key
if iterate == True:
i=0
while i<len(data_json['values']):
id_rule = data_json['values'][i]['id']
while i<len(data_json[iterative_key]):
id_rule = data_json[iterative_key][i]['id']
rule = requests.get(''.join(YOUR_DT_API_URL) + endpoint +"/"+id_rule, headers=headers, cookies=dict(cookies), verify=False);
f = open(directory+"/"+id_rule+".json", "w")
json_data = json.loads(rule.text)