summaryrefslogtreecommitdiff
path: root/scripts/metrics
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/metrics')
-rw-r--r--scripts/metrics/slp_conv.py73
-rw-r--r--scripts/metrics/viewer_asset_logs.py10
-rwxr-xr-xscripts/metrics/viewerstats.py54
3 files changed, 105 insertions, 32 deletions
diff --git a/scripts/metrics/slp_conv.py b/scripts/metrics/slp_conv.py
new file mode 100644
index 0000000000..27f922b74a
--- /dev/null
+++ b/scripts/metrics/slp_conv.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+"""\
+@file slp_conv.py
+@author Callum Prentice
+@date 2021-01-26
+@brief Convert a Second Life Performance (SLP) file generated
+ by the Viewer into an comma separated value (CSV) file
+ for import into spreadsheets and other data analytics tools.
+
+$LicenseInfo:firstyear=2021&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2021, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+$/LicenseInfo$
+"""
+
+from llbase import llsd
+import argparse
+
+parser = argparse.ArgumentParser(
+ description="Converts Viewer SLP files into CSV for import into spreadsheets etc."
+)
+parser.add_argument(
+ "infilename",
+ help="Name of SLP file to read",
+)
+parser.add_argument(
+ "outfilename",
+ help="Name of CSV file to create",
+)
+args = parser.parse_args()
+
+with open(args.infilename, "r") as slp_file:
+ slps = slp_file.readlines()
+ print "Reading from %s - %d items" % (args.infilename, len(slps))
+
+ with open(args.outfilename, "w") as csv_file:
+
+ print "Writing to %s" % args.outfilename
+
+ for index, each_slp in enumerate(slps):
+ slp_entry = llsd.parse(each_slp)
+
+ first_key = slp_entry.keys()[0]
+
+ # first entry so write column headers
+ if index == 0:
+ line = ""
+ for key, value in slp_entry[first_key].iteritems():
+ line += key
+ line += ", "
+ csv_file.write("entry, %s, \n" % line)
+ # write line of data
+ line = ""
+ for key, value in slp_entry[first_key].iteritems():
+ line += str(value)
+ line += ", "
+ csv_file.write("%s, %s, \n" % (first_key, str(line)))
diff --git a/scripts/metrics/viewer_asset_logs.py b/scripts/metrics/viewer_asset_logs.py
index e48286f696..0365936188 100644
--- a/scripts/metrics/viewer_asset_logs.py
+++ b/scripts/metrics/viewer_asset_logs.py
@@ -40,7 +40,7 @@ def get_metrics_record(infiles):
context = iter(context)
# get the root element
- event, root = context.next()
+ event, root = next(context)
try:
for event, elem in context:
if event == "end" and elem.tag == "llsd":
@@ -48,7 +48,7 @@ def get_metrics_record(infiles):
sd = llsd.parse_xml(xmlstr)
yield sd
except etree.XMLSyntaxError:
- print "Fell off end of document"
+ print("Fell off end of document")
f.close()
@@ -56,7 +56,7 @@ def update_stats(stats,rec):
for region in rec["regions"]:
region_key = (region["grid_x"],region["grid_y"])
#print "region",region_key
- for field, val in region.iteritems():
+ for field, val in region.items():
if field in ["duration","grid_x","grid_y"]:
continue
if field == "fps":
@@ -96,7 +96,7 @@ if __name__ == "__main__":
for key in sorted(stats.keys()):
val = stats[key]
if val["count"] > 0:
- print key,"count",val["count"],"mean_time",val["sum"]/val["count"],"mean_bytes",val["sum_bytes"]/val["count"],"net bytes/sec",val["sum_bytes"]/val["sum"],"enqueued",val["enqueued"],"dequeued",val["dequeued"]
+ print(key,"count",val["count"],"mean_time",val["sum"]/val["count"],"mean_bytes",val["sum_bytes"]/val["count"],"net bytes/sec",val["sum_bytes"]/val["sum"],"enqueued",val["enqueued"],"dequeued",val["dequeued"])
else:
- print key,"count",val["count"],"enqueued",val["enqueued"],"dequeued",val["dequeued"]
+ print(key,"count",val["count"],"enqueued",val["enqueued"],"dequeued",val["dequeued"])
diff --git a/scripts/metrics/viewerstats.py b/scripts/metrics/viewerstats.py
index f7be3d967e..7e19539e15 100755
--- a/scripts/metrics/viewerstats.py
+++ b/scripts/metrics/viewerstats.py
@@ -54,11 +54,11 @@ def show_stats_by_key(recs,indices,settings_sd = None):
v = tuple(v)
per_key_cnt[k][v] += 1
except Exception as e:
- print "err", e
- print "d", d, "k", k, "v", v
+ print("err", e)
+ print("d", d, "k", k, "v", v)
raise
mc = cnt.most_common()
- print "========================="
+ print("=========================")
keyprefix = ""
if len(indices)>0:
keyprefix = ".".join(indices) + "."
@@ -67,32 +67,32 @@ def show_stats_by_key(recs,indices,settings_sd = None):
bigc = m[1]
unset_cnt = len(recs) - bigc
kmc = per_key_cnt[k].most_common(5)
- print i, keyprefix+str(k), bigc
+ print(i, keyprefix+str(k), bigc)
if settings_sd is not None and k in settings_sd and "Value" in settings_sd[k]:
- print " ", "default",settings_sd[k]["Value"],"count",unset_cnt
+ print(" ", "default",settings_sd[k]["Value"],"count",unset_cnt)
for v in kmc:
- print " ", "value",v[0],"count",v[1]
+ print(" ", "value",v[0],"count",v[1])
if settings_sd is not None:
- print "Total keys in settings", len(settings_sd.keys())
+ print("Total keys in settings", len(settings_sd.keys()))
unused_keys = list(set(settings_sd.keys()) - set(cnt.keys()))
unused_keys_non_str = [k for k in unused_keys if settings_sd[k]["Type"] != "String"]
unused_keys_str = [k for k in unused_keys if settings_sd[k]["Type"] == "String"]
# Things that no one in the sample has set to a non-default value. Possible candidates for removal.
- print "\nUnused_keys_non_str", len(unused_keys_non_str)
- print "======================"
- print "\n".join(sorted(unused_keys_non_str))
+ print("\nUnused_keys_non_str", len(unused_keys_non_str))
+ print( "======================")
+ print("\n".join(sorted(unused_keys_non_str)))
# Strings are not currently logged, so we have no info on usage.
- print "\nString keys (usage unknown)", len(unused_keys_str)
- print "======================"
- print "\n".join(sorted(unused_keys_str))
+ print("\nString keys (usage unknown)", len(unused_keys_str))
+ print( "======================")
+ print("\n".join(sorted(unused_keys_str)))
# Things that someone has set but that aren't recognized settings.
unrec_keys = list(set(cnt.keys()) - set(settings_sd.keys()))
- print "\nUnrecognized keys", len(unrec_keys)
- print "======================"
- print "\n".join(sorted(unrec_keys))
+ print("\nUnrecognized keys", len(unrec_keys))
+ print( "======================")
+ print("\n".join(sorted(unrec_keys)))
result = (settings_sd.keys(), unused_keys_str, unused_keys_non_str, unrec_keys)
return result
@@ -138,7 +138,7 @@ def get_used_strings(root_dir):
for dir_name, sub_dir_list, file_list in os.walk(root_dir):
for fname in file_list:
if fname in ["settings.xml", "settings.xml.edit", "settings_per_account.xml"]:
- print "skip", fname
+ print("skip", fname)
continue
(base,ext) = os.path.splitext(fname)
#if ext not in [".cpp", ".hpp", ".h", ".xml"]:
@@ -155,8 +155,8 @@ def get_used_strings(root_dir):
for m in ms:
#print "used_str",m
used_str.add(m)
- print "skipped extensions", skipped_ext
- print "got used_str", len(used_str)
+ print("skipped extensions", skipped_ext)
+ print("got used_str", len(used_str))
return used_str
@@ -171,7 +171,7 @@ if __name__ == "__main__":
args = parser.parse_args()
for fname in args.infiles:
- print "process", fname
+ print("process", fname)
df = pd.read_csv(fname,sep='\t')
#print "DF", df.describe()
jstrs = df['RAW_LOG:BODY']
@@ -182,12 +182,12 @@ if __name__ == "__main__":
show_stats_by_key(recs,[])
show_stats_by_key(recs,["agent"])
if args.preferences:
- print "\nSETTINGS.XML"
+ print("\nSETTINGS.XML")
settings_sd = parse_settings_xml("settings.xml")
#for skey,svals in settings_sd.items():
# print skey, "=>", svals
(all_str,_,_,_) = show_stats_by_key(recs,["preferences","settings"],settings_sd)
- print
+ print()
#print "\nSETTINGS_PER_ACCOUNT.XML"
#settings_pa_sd = parse_settings_xml("settings_per_account.xml")
@@ -201,19 +201,19 @@ if __name__ == "__main__":
unref_strings = all_str_set-used_strings_set
# Some settings names are generated by appending to a prefix. Need to look for this case.
prefix_used = set()
- print "checking unref_strings", len(unref_strings)
+ print("checking unref_strings", len(unref_strings))
for u in unref_strings:
for k in range(6,len(u)):
prefix = u[0:k]
if prefix in all_str_set and prefix in used_strings_set:
prefix_used.add(u)
#print "PREFIX_USED",u,prefix
- print "PREFIX_USED", len(prefix_used), ",".join(list(prefix_used))
- print
+ print("PREFIX_USED", len(prefix_used), ",".join(list(prefix_used)))
+ print()
unref_strings = unref_strings - prefix_used
- print "\nUNREF_IN_CODE " + str(len(unref_strings)) + "\n"
- print "\n".join(list(unref_strings))
+ print("\nUNREF_IN_CODE " + str(len(unref_strings)) + "\n")
+ print("\n".join(list(unref_strings)))
settings_str = read_raw_settings_xml("settings.xml")
# Do this via direct string munging to generate minimal changeset
settings_edited = remove_settings(settings_str,unref_strings)