Skip to content

Commit

Permalink
Merge pull request #43 from newrelic/feature/metrics
Browse files Browse the repository at this point in the history
New Relic Metrics
  • Loading branch information
asllop authored Aug 2, 2022
2 parents ac45c49 + eb38b3e commit 98df227
Show file tree
Hide file tree
Showing 16 changed files with 725 additions and 224 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.vscode
out/
source/testFramework/
.DS_Store
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# CHANGELOG
All notable changes to this project will be documented in this file.

## [3.0.0] - 2022/07/22
### Add
- Metrics API.
- OOTB HTTP metrics.
### Remove
- Grouped events for `HTTP_CONNECT`/`HTTP_COMPLETE`.
### Fix
- Broken tests.

## [2.1.3] - 2022/05/16
### Fix
- Timing issue.

## [2.1.2] - 2022/04/21
### Add
- `timeSinceHttpRequest` attribute into `HTTP_RESPONSE` events.
Expand Down
195 changes: 138 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Will result in something like the following:
* [Data Model](#data-model)
   * [Roku System](#roku-system)
   * [Roku Video](#roku-video)
   * [Metrics](#metrics)
* [Ad Tracking](#ad-track)
* [Testing](#testing)
* [Open Source License](#open-source)
Expand Down Expand Up @@ -479,6 +480,44 @@ Example:
end if
```

**nrEnableHttpEvents**

```
function nrEnableHttpEvents(nr as Object) as Void
Description:
Enable HTTP_CONNECT/HTTP_COMPLETE events.
Arguments:
nr: New Relic Agent object.
Return:
Nothing.
Example:
nrEnableHttpEvents(nr)
```

**nrDisableHttpEvents**

```
function nrDisableHttpEvents(nr as Object) as Void
Description:
Disable HTTP_CONNECT/HTTP_COMPLETE events.
Arguments:
nr: New Relic Agent object.
Return:
Nothing.
Example:
nrDisableHttpEvents(nr)
```

**nrSetHarvestTime**

```
Expand Down Expand Up @@ -596,45 +635,6 @@ Example:
nrForceHarvestLogs(m.nr)
```

**nrSetGroupingPatternGenerator**

```
nrSetGroupingPatternGenerator(nr as Object, callbackNode as Object) as Void
Description:
Set pattern generator. This method accepts a Node that must contain a public function called "callback". This callback must return a string, that is used as a pattern to group HTTP_CONNECT and HTTP_COMPLETE events. The pattern generator callback is called every time a HTTP_CONNECT or HTTP_COMPLETE event happens and the raw event is passed as argument to the function.
It is reccomended to be called immediately or short after the New Relic Agent object is created.
Arguments:
nr: New Relic Agent object.
func: Pattern generator.
Return:
Nothing.
Example:
'Define a Node that contains the callback
<?xml version="1.0" encoding="UTF-8"?>
<component name="PatternGen" extends="Node">
<interface>
<function name="callback"/>
</interface>
<script type="text/brightscript">
<![CDATA[
function callback(ev as Object) as String
pattern = ... 'do whatever with ev attributes and generate a pattern
return pattern
end function
]]>
</script>
</component>
'And use it
patgen = createObject("roSGNode", "PatternGen")
nrSetGroupingPatternGenerator(m.nr, patgen)
```

**nrUpdateConfig**

```
Expand All @@ -655,6 +655,7 @@ Example:
nrUpdateConig(m.nr, config)
```

**nrSendLog**
```
nrSendLog(nr as Object, message as String, logtype as String, fields = invalid as Object) as Void
Expand All @@ -673,6 +674,72 @@ Return:
Example:
nrSendLog(m.nr, "This is a log", "console", {"key": "value"})
```

**nrSendMetric**
```
function nrSendMetric(nr as Object, name as String, value as dynamic, attr = invalid as Object) as Void
Description:
Record a gauge metric. Represents a value that can increase or decrease with time.
Arguments:
nr: New Relic Agent object.
name: Metric name
value: Metric value. Number.
attr: (optional) Metric attributes.
Return:
Nothing
Example:
nrSendMetric(m.nr, "test", 11.1, {"one": 1})
```

**nrSendCountMetric**
```
function nrSendCountMetric(nr as Object, name as String, value as dynamic, interval as Integer, attr = invalid as Object) as Void
Description:
Record a count metric. Measures the number of occurences of an event during a time interval.
Arguments:
nr: New Relic Agent object.
name: Metric name
value: Metric value. Number.
interval: Metric time interval in milliseconds.
attr: (optional) Metric attributes.
Return:
Nothing
Example:
nrSendCountMetric(m.nr, "test", 250, 1500, {"one": 1})
```

**nrSendSummaryMetric**
```
function nrSendSummaryMetric(nr as Object, name as String, interval as Integer, counter as dynamic, m_sum as dynamic, m_min as dynamic, m_max as dynamic, attr = invalid as Object) as Void
Description:
Record a summary metric. Used to report pre-aggregated data, or information on aggregated discrete events.
Arguments:
nr: New Relic Agent object.
name: Metric name
interval: Metric time interval in milliseconds.
count: Metric count.
m_sum: Metric value summation.
m_min: Metric minimum value.
m_max: Metric maximum value.
attr: (optional) Metric attributes.
Return:
Nothing.
Example:
nrSendSummaryMetric(m.nr, "test", 2000, 5, 1000, 100, 200)
```

<a name="data-model"></a>

### Data Model
Expand All @@ -698,10 +765,6 @@ This event groups all actions related to system tracking.
| `APP_STARTED` | The app did start. Generated by nrAppStarted function. |
| `SCENE_LOADED` | A scene did load. Generated by nrSceneLoaded function. |

##### 1.1.1 Grouping

`HTTP_CONNECT` and `HTTP_COMPLETE` are generated from [roSystemLogEvent](https://developer.roku.com/en-gb/docs/references/brightscript/events/rosystemlogevent.md), but there is no one-to-one correspondence because the volume of event traffic could be considerable. Instead, the New Relic Agent groups events and generates one New Relic event out of multiple Roku system log events. The default grouping criterion is using the host part of the requested URL, but the user can define custom patterns. Check out `nrSetGroupingPatternGenerator` documentation for further details.

#### 1.2 Attributes

There is a set of attributes common to all actions sent over a `RokuSystem` and others are specific to a certain action.
Expand Down Expand Up @@ -749,20 +812,18 @@ There is a set of attributes common to all actions sent over a `RokuSystem` and
| `httpCode` | Response code. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR`, `HTTP_RESPONSE` |
| `method` | HTTP method. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR`, `HTTP_REQUEST ` |
| `origUrl` | Original URL of request. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR`, `HTTP_REQUEST`, `HTTP_RESPONSE` |
| `matchPattern` | Matching pattern used in event grouping. | `HTTP_COMPLETE`, `HTTP_CONNECT` |
| `status` | Current request status. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR` |
| `targetIp` | Target IP address of request. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR` |
| `url` | Actual URL of request. | `HTTP_COMPLETE`, `HTTP_CONNECT`, `HTTP_ERROR` |
| `counter` | Number of actual network events grouped in. | `HTTP_COMPLETE`, `HTTP_CONNECT` |
| `bytesDownloaded` | Number of bytes downloaded. Summation if grouped. | `HTTP_COMPLETE` |
| `bytesUploaded` | Number of bytes uploaded. Summation if grouped. | `HTTP_COMPLETE` |
| `connectTime` | Total connection time. Average if grouped. | `HTTP_COMPLETE` |
| `bytesDownloaded` | Number of bytes downloaded. | `HTTP_COMPLETE` |
| `bytesUploaded` | Number of bytes uploaded. | `HTTP_COMPLETE` |
| `connectTime` | Total connection time. | `HTTP_COMPLETE` |
| `contentType` | Mime type of response body. | `HTTP_COMPLETE` |
| `dnsLookupTime` | DNS lookup time. Average if grouped. | `HTTP_COMPLETE` |
| `downloadSpeed` | Download speed. Average if grouped. | `HTTP_COMPLETE` |
| `firstByteTime` | Time elapsed until the first bytes arrived. Average if grouped. | `HTTP_COMPLETE` |
| `transferTime` | Total transfer time. Average if grouped. | `HTTP_COMPLETE` |
| `uploadSpeed` | Upload speed. Average if grouped. | `HTTP_COMPLETE` |
| `dnsLookupTime` | DNS lookup time. | `HTTP_COMPLETE` |
| `downloadSpeed` | Download speed. | `HTTP_COMPLETE` |
| `firstByteTime` | Time elapsed until the first bytes arrived. | `HTTP_COMPLETE` |
| `transferTime` | Total transfer time. | `HTTP_COMPLETE` |
| `uploadSpeed` | Upload speed. | `HTTP_COMPLETE` |
| `bandwidth` | Bandwidth. | `BANDWIDTH_MINUTE` |
| `lastExitOrTerminationReason` | The reason for the last app exit / termination. | `APP_STARTED` |
| `splashTime` | The splash time in ms. | `APP_STARTED` |
Expand All @@ -782,7 +843,6 @@ This event groups all actions related to video tracking.

#### 2.1 Actions


| Action Name | Description |
|---|---|
| `PLAYER_READY` | Player is ready to start working. It happens when the video agent is started. |
Expand Down Expand Up @@ -856,8 +916,29 @@ For video events, the common attributes include all `RokuSystem` common attribut
| `licenseStatusStatus` | Property `status` from Video object licenseStatus. | `CONTENT_ERROR`, `LICENSE_STATUS` |
| `isInitialBuffering` | Is the initial buffering event, and not a rebuffering. In playlists it only happens at the beginning, and not on every video. | `CONTENT_BUFFER_*` |

<a name="ad-track"></a>
<a name="metrics"></a>
#### 3. Metrics

The Roku agent generates the following metrics OOTB:

| Metric Name | Associated event | Metric type | Description |
|---|---|---|---|
| `roku.http.connect.count` | `HTTP_CONNECT` | count | Number of `HTTP_CONNECT` events generated in a period of time. |
| `roku.http.complete.count` | `HTTP_COMPLETE` | count | Number of `HTTP_COMPLETE` events generated in a period of time. |
| `roku.http.complete.connectTime` | `HTTP_COMPLETE` | gauge | Time taken to connect to the server in seconds. |
| `roku.http.complete.dnsTime` | `HTTP_COMPLETE` | gauge | DNS name resolution time in seconds. |
| `roku.http.complete.downSpeed` | `HTTP_COMPLETE` | gauge | Transfer download speed in bytes per second. |
| `roku.http.complete.firstByteTime` | `HTTP_COMPLETE` | gauge | Time taken to receive the first byte from the server in seconds. |
| `roku.http.complete.upSpeed` | `HTTP_COMPLETE` | gauge | Transfer upload speed in bytes per second. |
| `roku.http.error.count` | `HTTP_ERROR` | count | Number of `HTTP_ERROR` events generated in a period of time. |
| `roku.http.request.count` | `HTTP_REQUEST` | count | Number of `HTTP_REQUEST` events generated in a period of time. |
| `roku.http.response.count` | `HTTP_RESPONSE` | count | Number of `HTTP_RESPONSE` events generated in a period of time. |
| `roku.http.response.error.count` | `HTTP_RESPONSE` | count | Number of `HTTP_REQUEST` events generated in a period of time, that returned an error. |
| `roku.http.response.time` | `HTTP_RESPONSE` | gauge | Time since request in milliseconds. |

Each metric is associated with an event generated by the agent.

<a name="ad-track"></a>
### Ad Tracking

The Roku Video Agent also provides Ad events monitoring. Currently we support two different Ad APIs: [Roku Advertising Framework (RAF)](https://developer.roku.com/en-gb/docs/developer-program/advertising/roku-advertising-framework.md) and [Google IMA](https://developers.google.com/interactive-media-ads/docs/sdks/roku).
Expand Down Expand Up @@ -1008,10 +1089,10 @@ Not all events and attributes are supported in all Ad trackers.
To run the unit tests, first copy the file `UnitTestFramework.brs` from [unit-testing-framework](https://github.com/rokudev/unit-testing-framework) to `source/testFramework/`. Then install the demo channel provided in the present repo and from a terminal run:

```bash
curl -d '' 'http://ROKU_IP:8060/launch/dev?RunTests=true'
./test.sh ROKU_IP
```

Where `ROKU_IP` is the address of the Roku device where the channel is installed. Connect to the debug terminal (port 8085) to see test results.
Where `ROKU_IP` is the address of the Roku device where the channel is installed. Connect to the debug terminal (port 8085) to see test results. You can also provide the dev password as a second argument if you want to compile and deploy before running tests.

### Debugging
Network proxying is supported using URL re-write (see [App Level Proxying](https://rokulikeahurricane.io/proxying_network_requests)). To send all network requests via a proxy call `nrUpdateConfig()` function with the `proxyUrl` parameter object property. Be sure to specify the same URL delimiter as your proxy re-write rule.
Expand Down
Loading

0 comments on commit 98df227

Please sign in to comment.