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""" 16Utility functions for metrics. 17""" 18 19import os 20import platform 21import time 22 23from . import metrics 24from . import metrics_base 25 26 27def static_var(varname, value): 28 """Decorator to cache static variable.""" 29 def fun_var_decorate(func): 30 """Set the static variable in a function.""" 31 setattr(func, varname, value) 32 return func 33 return fun_var_decorate 34 35 36@static_var("start_time", []) 37def get_start_time(): 38 """Get start time. 39 40 Return: 41 start_time: Start time in seconds. Return cached start_time if exists, 42 time.time() otherwise. 43 """ 44 if not get_start_time.start_time: 45 get_start_time.start_time = time.time() 46 return get_start_time.start_time 47 48 49def convert_duration(diff_time_sec): 50 """Compute duration from time difference. 51 52 A Duration represents a signed, fixed-length span of time represented 53 as a count of seconds and fractions of seconds at nanosecond 54 resolution. 55 56 Args: 57 dur_time_sec: The time in seconds as a floating point number. 58 59 Returns: 60 A dict of Duration. 61 """ 62 seconds = int(diff_time_sec) 63 nanos = int((diff_time_sec - seconds)*10**9) 64 return {'seconds': seconds, 'nanos': nanos} 65 66 67def send_exit_event(exit_code, stacktrace='', logs=''): 68 """Log exit event and flush all events to clearcut. 69 70 Args: 71 exit_code: An integer of exit code. 72 stacktrace: A string of stacktrace. 73 logs: A string of logs. 74 """ 75 clearcut = metrics.AtestExitEvent( 76 duration=convert_duration(time.time()-get_start_time()), 77 exit_code=exit_code, 78 stacktrace=stacktrace, 79 logs=logs) 80 # pylint: disable=no-member 81 if clearcut: 82 clearcut.flush_events() 83 84 85def send_start_event(tool_name, command_line='', test_references='', 86 cwd=None, operating_system=None): 87 """Log start event of clearcut. 88 89 Args: 90 tool_name: A string of the asuite product name. 91 command_line: A string of the user input command. 92 test_references: A string of the input tests. 93 cwd: A string of current path. 94 operating_system: A string of user's operating system. 95 """ 96 if not cwd: 97 cwd = os.getcwd() 98 if not operating_system: 99 operating_system = platform.platform() 100 # Without tool_name information, asuite's clearcut client will not send 101 # event to server. 102 metrics_base.MetricsBase.tool_name = tool_name 103 get_start_time() 104 metrics.AtestStartEvent(command_line=command_line, 105 test_references=test_references, 106 cwd=cwd, 107 os=operating_system) 108