Preparation for automated benchmarks (#1923)

* ly_test_tools: Add filebeat_client module from o3de-mars.

Slightly modified with default parameters and exceptions in order to act as an individual component.

Signed-off-by: Cynthia Lin <cyntlin@amazon.com>

* scripts: Remove timestamp_aggregator.py to prepare for moving into ASV automated test repository.

Signed-off-by: Cynthia Lin <cyntlin@amazon.com>
This commit is contained in:
Cynthia Lin
2021-07-09 11:28:18 -07:00
committed by GitHub
parent 4826f1b653
commit eb9304c28d
2 changed files with 67 additions and 74 deletions
@@ -1,74 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
from genericpath import isdir
from argparse import ArgumentParser
import json
from pathlib import Path
import time
# this allows us to add additional data if necessary, e.g. frame_test_timestamps.json
is_timestamp_file = lambda file: file.name.startswith('frame') and file.name.endswith('_timestamps.json')
ns_to_ms = lambda time: time / 1e6
def main(logs_dir):
frame_count = 0
frame_time_total = 0
frame_time_max = 0
pass_stats = {}
print(f'Analyzing frame timestamp logs in {logs_dir}')
# go through files in alphabetical order (remove sorted() if not necessary)
for file in sorted(logs_dir.iterdir(), key=lambda file: len(file.name)):
if file.is_dir() or not is_timestamp_file(file):
continue
data = json.loads(file.read_text())
entries = data['ClassData']['timestampEntries']
frame_time = 0
for entry in entries:
name = entry['passName']
time_ns = entry['timestampResultInNanoseconds']
pass_entry = pass_stats.get(name, {'max': 0, 'total': 0})
pass_entry['max'] = max(time_ns, pass_entry['max'])
pass_entry['total'] += time_ns
pass_stats[name] = pass_entry
frame_time += time_ns
frame_time_total += frame_time
frame_name = file.name.split('_')[0]
print(f'- Total time for frame {frame_name}: {ns_to_ms(frame_time)}ms')
frame_time_max = max(frame_time, frame_time_max)
frame_count += 1
if frame_count < 1:
print(f'No logs were found in {base_dir}')
exit(1)
frame_avg = frame_time_total / frame_count
print(f'Avg time across {frame_count} frames: {ns_to_ms(frame_avg)}ms')
print(f'Max frame time: {ns_to_ms(frame_time_max)}ms')
print('Pass statistics:')
for name, stat in pass_stats.items():
avg_ms = ns_to_ms(stat['total'] / frame_count)
max_ms = ns_to_ms(stat['max'])
print(f'- {name}: {avg_ms}ms avg, {max_ms}ms max')
if __name__ == '__main__':
parser = ArgumentParser(description='Gathers statistics from a group of pass timestamp logs')
parser.add_argument('path', help='Path to the directory containing the pass timestamp logs')
args = parser.parse_args()
base_dir = Path(args.path)
if not base_dir.exists():
raise FileNotFoundError('Invalid path provided')
main(base_dir)
@@ -0,0 +1,67 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import datetime
import json
import socket
class FilebeatExn(Exception):
pass
class FilebeatClient(object):
def __init__(self, logger, host="127.0.0.1", port=9000, timeout=20):
self._logger = logger.getChild("filebeat_client")
self._filebeat_host = host
self._filebeat_port = port
self._socket_timeout = timeout
self._socket = None
self._open_socket()
def send_event(self, payload, index, timestamp=None, pipeline="filebeat"):
if timestamp is None:
timestamp = datetime.datetime.utcnow().timestamp()
event = {
"index": index,
"timestamp": timestamp,
"pipeline": pipeline,
"payload": json.dumps(payload)
}
# Serialise event, add new line and encode as UTF-8 before sending to Filebeat.
data = json.dumps(event, sort_keys=True) + "\n"
data = data.encode()
self._logger.debug(f"-> {data}")
self._send_data(data)
def _open_socket(self):
self._logger.info(f"Connecting to Filebeat on {self._filebeat_host}:{self._filebeat_port}")
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.settimeout(self._socket_timeout)
try:
self._socket.connect((self._filebeat_host, self._filebeat_port))
except (ConnectionError, socket.timeout):
raise FilebeatExn("Failed to connect to Filebeat") from None
def _send_data(self, data):
total_sent = 0
while total_sent < len(data):
try:
sent = self._socket.send(data[total_sent:])
except BrokenPipeError:
self._logger.debug("Filebeat socket closed by peer")
self._socket.close()
self._open_socket()
total_sent = 0
else:
total_sent = total_sent + sent