Print the version to check that Pandas is available. If the module is not found, install pandas with pip install pandas.

In [ ]:
import pandas as pd
print(pd.__version__)
1.4.0

Import the Json file with read_json. This will make a Pandas DataFrame (a table).

In [ ]:
df = pd.read_json("Debug_Log.json")

Print the first five rows to see what the table looks like.

In [ ]:
df.head(5)
Out[ ]:
ticks peer type event arg1 arg2 arg3 objectid componentid
0 637799313741476033 2990c448-6701d991 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN
1 637799313890915697 2990c448-6701d991 Ubiq.Voip.VoipPeerConnectionManager CreatePeerConnectionForPeer 0b6034cb-5c980872 21119b9e-9028aafa NaN 2990c448-6701d991 50.0
2 637799313890975713 2990c448-6701d991 Ubiq.Voip.VoipPeerConnectionManager RequestPeerConnection 0b6034cb-5c980872 21119b9e-9028aafa NaN 2990c448-6701d991 50.0
3 637799313891015701 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 b0edec0e-fcf7792a True 7725a971-a3692643 49018.0
4 637799313891055695 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 43b53edd-7c900c8f False 7725a971-a3692643 49018.0

We can use Pandas to filter and process the structured logs. Use Unique to find all the event types seen during the session.

In [ ]:
df.type.unique()
Out[ ]:
array(['Ubiq.Messaging.NetworkScene',
       'Ubiq.Voip.VoipPeerConnectionManager',
       'Ubiq.Samples.NetworkSpawner'], dtype=object)

Pandas can perform vector comparisons, and filter DataFrames by row indices. Select all the SpawnObject events.

In [ ]:
df[df.event == "SpawnObject"].head(5)
Out[ ]:
ticks peer type event arg1 arg2 arg3 objectid componentid
3 637799313891015701 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 b0edec0e-fcf7792a True 7725a971-a3692643 49018.0
4 637799313891055695 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 43b53edd-7c900c8f False 7725a971-a3692643 49018.0
5 637799313935475736 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 bf000355-ece0ea90 False 7725a971-a3692643 49018.0
6 637799313951775722 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 ba22e255-c3d84eb4 False 7725a971-a3692643 49018.0
7 637799313967325709 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 1ad3fc82-d41c3b8f False 7725a971-a3692643 49018.0

The Shape member shows the size of the result

In [ ]:
df[df.event == "SpawnObject"].shape
Out[ ]:
(22, 9)

The Pandas merge method is used to perform inner and outer joins to relate different log events. We merge the Awake events with the local SpawnObject events based on the NetworkScene Ids (peer).

In [ ]:
spawn = df[df.event == "SpawnObject"]
awake = df[df.event == "Awake"]
f = pd.merge(spawn,awake,how="left",left_on="peer",right_on="peer")
f.head(5)
Out[ ]:
ticks_x peer type_x event_x arg1_x arg2_x arg3_x objectid_x componentid_x ticks_y type_y event_y arg1_y arg2_y arg3_y objectid_y componentid_y
0 637799313891015701 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 b0edec0e-fcf7792a True 7725a971-a3692643 49018.0 637799313741476033 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN
1 637799313891055695 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 2 43b53edd-7c900c8f False 7725a971-a3692643 49018.0 637799313741476033 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN
2 637799313935475736 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 bf000355-ece0ea90 False 7725a971-a3692643 49018.0 637799313741476033 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN
3 637799313951775722 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 ba22e255-c3d84eb4 False 7725a971-a3692643 49018.0 637799313741476033 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN
4 637799313967325709 2990c448-6701d991 Ubiq.Samples.NetworkSpawner SpawnObject 1 1ad3fc82-d41c3b8f False 7725a971-a3692643 49018.0 637799313741476033 Ubiq.Messaging.NetworkScene Awake DESKTOP-F1J0MRR System Product Name (ASUS) f73fe01b1e21031d49274a1491d1d6b5714c92e9 NaN NaN

We can perform arithmetic operations too. We use string operations, boolean arrays and size to find the number of distinct objects spawned by the Oculus Quest.

In [ ]:
is_quest = f.arg2_y.astype(str).str.contains("Quest")
is_owner = f.arg3_x.astype(bool)
spawned_ids = f[is_quest & is_owner].arg2_x
spawned_ids.unique().size
Out[ ]:
5
In [ ]: