• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    from urllib.request import Request
24    from urllib.request import urlopen
25except ImportError:
26    # for compatibility of asuite_metrics_lib_tests and asuite_cc_lib_tests.
27    from urllib2 import Request
28    from urllib2 import urlopen
29
30_JSON_HEADERS = {'Content-Type': 'application/json'}
31_METRICS_RESPONSE = 'done'
32_METRICS_TIMEOUT = 2 #seconds
33_META_FILE = os.path.join(os.path.expanduser('~'),
34                          '.config', 'asuite', '.metadata')
35_ANDROID_BUILD_TOP = 'ANDROID_BUILD_TOP'
36
37UNUSED_UUID = '00000000-0000-4000-8000-000000000000'
38
39
40#pylint: disable=broad-except
41def log_event(metrics_url, unused_key_fallback=True, **kwargs):
42    """Base log event function for asuite backend.
43
44    Args:
45        metrics_url: String, URL to report metrics to.
46        unused_key_fallback: Boolean, If True and unable to get grouping key,
47                            use a unused key otherwise return out. Sometimes we
48                            don't want to return metrics for users we are
49                            unable to identify. Default True.
50        kwargs: Dict, additional fields we want to return metrics for.
51    """
52    try:
53        try:
54            key = str(_get_grouping_key())
55        except Exception:
56            if not unused_key_fallback:
57                return
58            key = UNUSED_UUID
59        data = {'grouping_key': key,
60                'run_id': str(uuid.uuid4())}
61        if kwargs:
62            data.update(kwargs)
63        data = json.dumps(data)
64        request = Request(metrics_url, data=data,
65                          headers=_JSON_HEADERS)
66        response = urlopen(request, timeout=_METRICS_TIMEOUT)
67        content = response.read()
68        if content != _METRICS_RESPONSE:
69            raise Exception('Unexpected metrics response: %s' % content)
70    except Exception as e:
71        logging.debug('Exception sending metrics: %s', e)
72
73
74def _get_grouping_key():
75    """Get grouping key. Returns UUID.uuid4."""
76    if os.path.isfile(_META_FILE):
77        with open(_META_FILE) as f:
78            try:
79                return uuid.UUID(f.read(), version=4)
80            except ValueError:
81                logging.debug('malformed group_key in file, rewriting')
82    # TODO: Delete get_old_key() on 11/17/2018
83    key = _get_old_key() or uuid.uuid4()
84    dir_path = os.path.dirname(_META_FILE)
85    if os.path.isfile(dir_path):
86        os.remove(dir_path)
87    try:
88        os.makedirs(dir_path)
89    except OSError as e:
90        if not os.path.isdir(dir_path):
91            raise e
92    with open(_META_FILE, 'w+') as f:
93        f.write(str(key))
94    return key
95
96
97def _get_old_key():
98    """Get key from old meta data file if exists, else return None."""
99    old_file = os.path.join(os.environ[_ANDROID_BUILD_TOP],
100                            'tools/asuite/atest', '.metadata')
101    key = None
102    if os.path.isfile(old_file):
103        with open(old_file) as f:
104            try:
105                key = uuid.UUID(f.read(), version=4)
106            except ValueError:
107                logging.debug('error reading old key')
108        os.remove(old_file)
109    return key
110