Generalizing the stats hierarchy

Harald,

In draft-alvestrand-rtcweb-stats-registry-00.txt, you observe that
there are times when a single named statistics value actually
corresponds to a number of elements and you would like to be able to
address them individually. You suggest handling this case with the
convention of appending a ".X" to the stat in question, but
I think this actually points to the need towards genuinely
hierarchical stats.

Consider the case where you want to examine every aspect of ICE,
which I think there is general consensus we need. At this point
we have the following containment hierarchy:

  - Media Stream  [W3C name: track]
  - Component     [RTP or RTCP]
  - Local candidate
    - State
    - Check history
    - Estimated RTT

This seems pretty deep to represent cleanly in the existing hierarchy
but would fit well into a more generic structure.

Here's a strawman to give you an idea of what I have in mind:

- Instead of being just opaque strings, stats identifiers
  should be dot-separated strings, with dots separating
  levels in the hierarchy.

- When registered, each stats identifier must be one of:

  * value -- the value is in the stat itself
  * array -- the stat contains a list of values in an array
    (i.e., [])
  * dictionary -- the stat contains a list of values in a
    dictionary (i.e., {})

- You can call getValue() at any level in the hierarchy
  and what you get depends on the identifier type. You
  can subaddress arrays and dictionaries by including
  the index/key in the identifier (as shown below).


Reworking your ICE example in this fashion would give us something like this:

{ local: { timestamp: 12345, stats: {
         SentPackets: 47,
         SentOctets: 4444,
         ReceivedPackets: 33,
         ReceivedOctets: 2346,
         ICE: [
           {
             State: Succeeded
             Used: True,
             LocalIpAddr: '129.241.1.99',
             RemoteIpAddr:'234.978.4.3'
           },
           {
             LocalIPAddr: '10.0.0.1',
             RemoteIPAddr: '10.0.1.24',
             State: Succeeded
             Used: False
           }
         ]
}}}

ISTM that this places things that naturally go together together,
and also makes it easier to build processing engines without a lot
of string manipulation.


If I am reading the current API correctly, the only way to actually
get at a statistics value is to do .getValue() on an RTCStatsReport.
In this case, the code would then be something like this:

   report.getValue('SentPackets') --> 47
   report.getValue('ICE') -->
         ICE: [
           {
             State: Succeeded
             Used: True,
             LocalIpAddr: '129.241.1.99',
             RemoteIpAddr:'234.978.4.3'
           },
           {
             LocalIPAddr: '10.0.0.1',
             RemoteIPAddr: '10.0.1.24',
             State: Succeeded
             Used: False
           }
         ]


   report.getValue('ICE.0') -->
           {
             State: Succeeded
             Used: True,
             LocalIpAddr: '129.241.1.99',
             RemoteIpAddr:'234.978.4.3'
           }

   report.getValue('ICE.0.State') --> 'Succeeded'

Thoughts?
-Ekr

Received on Monday, 24 September 2012 15:14:17 UTC