1# Copyright 2018, The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Asuite simple Metrics Functions""" 16 17import json 18import logging 19import os 20import uuid 21 22try: 23 # PYTHON2 24 from urllib2 import Request 25 from urllib2 import urlopen 26except ImportError: 27 # PYTHON3 28 from urllib.request import Request 29 from urllib.request import urlopen 30 31 32_JSON_HEADERS = {'Content-Type': 'application/json'} 33_METRICS_RESPONSE = 'done' 34_METRICS_TIMEOUT = 2 #seconds 35_META_FILE = os.path.join(os.path.expanduser('~'), 36 '.config', 'asuite', '.metadata') 37_ANDROID_BUILD_TOP = 'ANDROID_BUILD_TOP' 38 39UNUSED_UUID = '00000000-0000-4000-8000-000000000000' 40 41 42#pylint: disable=broad-except 43def log_event(metrics_url, unused_key_fallback=True, **kwargs): 44 """Base log event function for asuite backend. 45 46 Args: 47 metrics_url: String, URL to report metrics to. 48 unused_key_fallback: Boolean, If True and unable to get grouping key, 49 use a unused key otherwise return out. Sometimes we 50 don't want to return metrics for users we are 51 unable to identify. Default True. 52 kwargs: Dict, additional fields we want to return metrics for. 53 """ 54 try: 55 try: 56 key = str(_get_grouping_key()) 57 except Exception: 58 if not unused_key_fallback: 59 return 60 key = UNUSED_UUID 61 data = {'grouping_key': key, 62 'run_id': str(uuid.uuid4())} 63 if kwargs: 64 data.update(kwargs) 65 data = json.dumps(data) 66 request = Request(metrics_url, data=data, 67 headers=_JSON_HEADERS) 68 response = urlopen(request, timeout=_METRICS_TIMEOUT) 69 content = response.read() 70 if content != _METRICS_RESPONSE: 71 raise Exception('Unexpected metrics response: %s' % content) 72 except Exception as e: 73 logging.debug('Exception sending metrics: %s', e) 74 75 76def _get_grouping_key(): 77 """Get grouping key. Returns UUID.uuid4.""" 78 if os.path.isfile(_META_FILE): 79 with open(_META_FILE) as f: 80 try: 81 return uuid.UUID(f.read(), version=4) 82 except ValueError: 83 logging.debug('malformed group_key in file, rewriting') 84 # TODO: Delete get_old_key() on 11/17/2018 85 key = _get_old_key() or uuid.uuid4() 86 dir_path = os.path.dirname(_META_FILE) 87 if os.path.isfile(dir_path): 88 os.remove(dir_path) 89 try: 90 os.makedirs(dir_path) 91 except OSError as e: 92 if not os.path.isdir(dir_path): 93 raise e 94 with open(_META_FILE, 'w+') as f: 95 f.write(str(key)) 96 return key 97 98 99def _get_old_key(): 100 """Get key from old meta data file if exists, else return None.""" 101 old_file = os.path.join(os.environ[_ANDROID_BUILD_TOP], 102 'tools/tradefederation/core/atest', '.metadata') 103 key = None 104 if os.path.isfile(old_file): 105 with open(old_file) as f: 106 try: 107 key = uuid.UUID(f.read(), version=4) 108 except ValueError: 109 logging.debug('error reading old key') 110 os.remove(old_file) 111 return key 112