Skip to content

Commit

Permalink
Add Telemetry (#264)
Browse files Browse the repository at this point in the history
* Add telemetry

NativeVision is looking to understand how our users are using the library
better. To do this, we've created a telemetry API to ingest events from the
application.

* Use deployed domain
* chore: version bump 2.24.0
* Run typescript build
  • Loading branch information
robertjcolley authored Feb 16, 2024
1 parent a380420 commit 52a330e
Show file tree
Hide file tree
Showing 20 changed files with 270 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ local.properties
build/
*.tgz
yarn.lock
.env

# Fastlane
ios/fastlane/report.xml
Expand Down
18 changes: 7 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# ViroReact

ViroReact is a library for developers to rapidly build augmented reality (AR) and virtual reality (VR) experiences. Developers write in React Native, and Viro runs their code natively across all mobile VR (including Google Daydream, Samsung Gear VR, and Google Cardboard for iOS and Android) and AR (iOS ARKit and Android ARCore) platforms.
ViroReact is a library for developers to rapidly build augmented reality (AR) and virtual reality (VR) experiences. Developers write in React Native and Viro runs their code natively across all mobile VR (including Google Daydream, Samsung Gear VR, and Google Cardboard for iOS and Android) and AR (iOS ARKit and Android ARCore) platforms.

<table>
<tr>
Expand All @@ -23,21 +23,17 @@ ViroReact is a library for developers to rapidly build augmented reality (AR) an
</tr>
</table>

# [Installing](readmes/INSTALL.md)

If you are integrating ViroReact into an existing project, have a look at our [Installation instructions](readmes/INSTALL.md).

If you are starting a fresh project with ViroReact, consider cloning our [starter kit](https://github.com/ViroCommunity/starter-kit) repo instead.

# Documentation

The documentation is found [here](https://viro-community.readme.io/docs/overview). Currently, the documentation is migrated with issues to code samples and broken links. If you would like to help fix these issues, either submit an edit or [get in touch](https://discord.gg/H3ksm5NhzT)!
[Documentation can be found here!](https://viro-community.readme.io/docs/overview). Currently, the documentation has some issues with code samples and broken links. If you would like to help fix these issues, either submit an edit or [get in touch](https://discord.gg/H3ksm5NhzT)!

# FAQ
## Getting Started

- _Older versions couldn't be submitted to Apple's app store due to use of `UIWebView`. Is this still a problem?_
If you are starting a fresh project with ViroReact, consider cloning one of our starter kits:

Reliance on `UIWebView` has been removed from the project, so you should not have this problem if using the `@viro-community/react-viro` package.
- [Expo + TypeScript](https://github.com/NativeVision/expo-starter-kit-typescript)
- [React Native](https://github.com/NativeVision/starter-kit)
- [Expo + JavaScript](https://github.com/NativeVision/expo-starter-kit)

# Examples

Expand Down
1 change: 1 addition & 0 deletions components/AR/ViroARScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { ViroBase } from "../ViroBase";
import { ViroCamera } from "../ViroCamera";
import { ViroTrackingStateConstants } from "../ViroConstants";
import { ViroCommonProps } from "./ViroCommonProps";
import { ViroTelemetry } from "../Telemetry";

const ViroCameraModule = NativeModules.ViroCameraModule;

Expand Down
2 changes: 2 additions & 0 deletions components/AR/ViroARSceneNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
ViroScene,
ViroSceneDictionary,
} from "../Types/ViroUtils";
import { ViroTelemetry } from "../Telemetry";

const ViroARSceneNavigatorModule = NativeModules.VRTARSceneNavigatorModule;

Expand Down Expand Up @@ -79,6 +80,7 @@ export class ViroARSceneNavigator extends React.Component<Props, State> {

constructor(props: Props) {
super(props);
ViroTelemetry.recordTelemetry("INIT", { ar: true });
let initialSceneTag = this.props.initialSceneKey;
if (initialSceneTag == null) {
initialSceneTag = this.getRandomTag();
Expand Down
103 changes: 103 additions & 0 deletions components/Telemetry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { VIRO_VERSION } from "../Utilities/ViroVersion";
import { Platform } from "react-native";

export class ViroTelemetry {
private static _isDisabled = false;
private static _isDebugging = false;
// TODO: use custom domain
// private static _telemetryUrl = "https://telemetry.nativevision.xyz";
private static _telemetryUrl = "https://native-vision-telemetry.onrender.com";
private static _timeout = 8000;

/**
* Allow a user to start debugging the telemetry to see what is sent.
*/
public static setDebugging() {
this._isDebugging = true;
}

/**
* Allow a user to opt out of telemetry.
*/
public static optOutTelemetry() {
this._isDisabled = true;
}

public static recordTelemetry(eventName: string, payload: any = {}) {
// Skip recording telemetry if the feature is disabled
if (this._isDisabled) return;
// Do not send the telemetry data if debugging. Users may use this feature
// to preview what data would be sent.
if (this._isDebugging) {
console.log(
`[telemetry] ` + JSON.stringify({ eventName, payload }, null, 2)
);
return;
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this._timeout);

payload = { ...payload, ...this.getAnonymousMeta() };

fetch(`${this._telemetryUrl}/api/v1/record`, {
method: "PUT",
body: JSON.stringify({ eventName, payload }),
headers: { "content-type": "application/json" },
signal: controller.signal,
})
.catch((e) => console.error(e))
.finally(() => clearTimeout(timeoutId));
}

private static getAnonymousMeta() {
let isExpo = false;
try {
const myModule = require("expo");
isExpo = true;
} catch (err) {
// send error to log file
}

try {
const traits = {
// expo
isExpo:
// @ts-ignore
Boolean(window?.expo) || false,
sdkVersion:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.sdkVersion || undefined,
androidPackage:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.android?.package ||
undefined,
iosBundleIdentifier:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.ios?.bundleIdentifier ||
undefined,
expoDebugMode:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.debugMode || undefined,
isDevice:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.isDevice || undefined,
// library version
viroVersion: VIRO_VERSION,
platform: Platform.OS,
deviceOsVersion: Platform.Version,
reactNativeVersion:
Platform.constants.reactNativeVersion.major +
"." +
Platform.constants.reactNativeVersion.minor +
"." +
Platform.constants.reactNativeVersion.patch,
};

return traits;
} catch (e) {
console.error(e);
}

return {};
}
}
1 change: 1 addition & 0 deletions components/Utilities/ViroVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const VIRO_VERSION = "2.40.0";
2 changes: 2 additions & 0 deletions components/Viro3DSceneNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ViroSceneDictionary,
} from "./Types/ViroUtils";
import { ViroScene } from "./ViroScene";
import { ViroTelemetry } from "./Telemetry";
const Viro3DSceneNavigatorModule = NativeModules.VRT3DSceneNavigatorModule;

var mathRandomOffset = 0;
Expand Down Expand Up @@ -93,6 +94,7 @@ export class Viro3DSceneNavigator extends React.Component<Props, State> {

constructor(props: Props) {
super(props);
ViroTelemetry.recordTelemetry("INIT", { vr: true });
var initialSceneTag = this.props.initialSceneKey;
if (initialSceneTag == null) {
initialSceneTag = this.getRandomTag();
Expand Down
1 change: 1 addition & 0 deletions components/ViroSceneNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ViroExitViroEvent } from "./Types/ViroEvents";
import { Viro3DPoint } from "./Types/ViroUtils";
import { ViroSceneDictionary } from "./Types/ViroUtils";
import { ViroScene } from "./ViroScene";
import { ViroTelemetry } from "./Telemetry";
var ViroSceneNavigatorModule = NativeModules.VRTSceneNavigatorModule;

var mathRandomOffset = 0;
Expand Down
2 changes: 2 additions & 0 deletions dist/components/AR/ViroARSceneNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.ViroARSceneNavigator = void 0;
const React = __importStar(require("react"));
const react_native_1 = require("react-native");
const Telemetry_1 = require("../Telemetry");
const ViroARSceneNavigatorModule = react_native_1.NativeModules.VRTARSceneNavigatorModule;
let mathRandomOffset = 0;
/**
Expand All @@ -46,6 +47,7 @@ class ViroARSceneNavigator extends React.Component {
_component = null;
constructor(props) {
super(props);
Telemetry_1.ViroTelemetry.recordTelemetry("INIT", { ar: true });
let initialSceneTag = this.props.initialSceneKey;
if (initialSceneTag == null) {
initialSceneTag = this.getRandomTag();
Expand Down
16 changes: 16 additions & 0 deletions dist/components/Telemetry/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export declare class ViroTelemetry {
private static _isDisabled;
private static _isDebugging;
private static _telemetryUrl;
private static _timeout;
/**
* Allow a user to start debugging the telemetry to see what is sent.
*/
static setDebugging(): void;
/**
* Allow a user to opt out of telemetry.
*/
static optOutTelemetry(): void;
static recordTelemetry(eventName: string, payload?: any): void;
private static getAnonymousMeta;
}
97 changes: 97 additions & 0 deletions dist/components/Telemetry/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ViroTelemetry = void 0;
const ViroVersion_1 = require("../Utilities/ViroVersion");
const react_native_1 = require("react-native");
class ViroTelemetry {
static _isDisabled = false;
static _isDebugging = false;
// TODO: use custom domain
// private static _telemetryUrl = "https://telemetry.nativevision.xyz";
static _telemetryUrl = "https://native-vision-telemetry.onrender.com";
static _timeout = 8000;
/**
* Allow a user to start debugging the telemetry to see what is sent.
*/
static setDebugging() {
this._isDebugging = true;
}
/**
* Allow a user to opt out of telemetry.
*/
static optOutTelemetry() {
this._isDisabled = true;
}
static recordTelemetry(eventName, payload = {}) {
// Skip recording telemetry if the feature is disabled
if (this._isDisabled)
return;
// Do not send the telemetry data if debugging. Users may use this feature
// to preview what data would be sent.
if (this._isDebugging) {
console.log(`[telemetry] ` + JSON.stringify({ eventName, payload }, null, 2));
return;
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this._timeout);
payload = { ...payload, ...this.getAnonymousMeta() };
fetch(`${this._telemetryUrl}/api/v1/record`, {
method: "PUT",
body: JSON.stringify({ eventName, payload }),
headers: { "content-type": "application/json" },
signal: controller.signal,
})
.catch((e) => console.error(e))
.finally(() => clearTimeout(timeoutId));
}
static getAnonymousMeta() {
let isExpo = false;
try {
const myModule = require("expo");
isExpo = true;
}
catch (err) {
// send error to log file
}
try {
const traits = {
// expo
isExpo:
// @ts-ignore
Boolean(window?.expo) || false,
sdkVersion:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.sdkVersion || undefined,
androidPackage:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.android?.package ||
undefined,
iosBundleIdentifier:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.ios?.bundleIdentifier ||
undefined,
expoDebugMode:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.debugMode || undefined,
isDevice:
// @ts-ignore
window?.expo?.modules?.ExponentConstants?.isDevice || undefined,
// library version
viroVersion: ViroVersion_1.VIRO_VERSION,
platform: react_native_1.Platform.OS,
deviceOsVersion: react_native_1.Platform.Version,
reactNativeVersion: react_native_1.Platform.constants.reactNativeVersion.major +
"." +
react_native_1.Platform.constants.reactNativeVersion.minor +
"." +
react_native_1.Platform.constants.reactNativeVersion.patch,
};
return traits;
}
catch (e) {
console.error(e);
}
return {};
}
}
exports.ViroTelemetry = ViroTelemetry;
1 change: 1 addition & 0 deletions dist/components/Utilities/ViroVersion.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export declare const VIRO_VERSION = "2.40.0";
4 changes: 4 additions & 0 deletions dist/components/Utilities/ViroVersion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VIRO_VERSION = void 0;
exports.VIRO_VERSION = "2.40.0";
2 changes: 2 additions & 0 deletions dist/components/Viro3DSceneNavigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.Viro3DSceneNavigator = void 0;
const React = __importStar(require("react"));
const react_native_1 = require("react-native");
const Telemetry_1 = require("./Telemetry");
const Viro3DSceneNavigatorModule = react_native_1.NativeModules.VRT3DSceneNavigatorModule;
var mathRandomOffset = 0;
/**
Expand All @@ -53,6 +54,7 @@ class Viro3DSceneNavigator extends React.Component {
}
constructor(props) {
super(props);
Telemetry_1.ViroTelemetry.recordTelemetry("INIT", { vr: true });
var initialSceneTag = this.props.initialSceneKey;
if (initialSceneTag == null) {
initialSceneTag = this.getRandomTag();
Expand Down
5 changes: 0 additions & 5 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* Copyright (c) 2016-present, Viro Media, Inc.
* All rights reserved.
*
*/
import { ViroAnimations } from "./components/Animation/ViroAnimations";
import { Viro3DObject } from "./components/Viro3DObject";
import { Viro360Image } from "./components/Viro360Image";
Expand Down
5 changes: 0 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
"use strict";
/**
* Copyright (c) 2016-present, Viro Media, Inc.
* All rights reserved.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ViroARTrackingReasonConstants = exports.Viro3DSceneNavigator = exports.ViroVRSceneNavigator = exports.ViroVideo = exports.ViroText = exports.ViroSpotLight = exports.ViroSpinner = exports.ViroSphere = exports.ViroSpatialSound = exports.ViroSoundField = exports.ViroSound = exports.ViroAnimatedComponent = exports.ViroAmbientLight = exports.ViroAnimatedImage = exports.Viro360Video = exports.Viro360Image = exports.Viro3DObject = exports.ViroAnimations = exports.ViroSkyBox = exports.ViroSceneNavigator = exports.ViroSurface = exports.ViroScene = exports.ViroQuad = exports.ViroPortalScene = exports.ViroPortal = exports.ViroPolyline = exports.ViroPolygon = exports.ViroParticleEmitter = exports.ViroOrbitCamera = exports.ViroOmniLight = exports.ViroNode = exports.ViroMaterialVideo = exports.ViroARCamera = exports.ViroMaterials = exports.ViroImage = exports.ViroLightingEnvironment = exports.ViroGeometry = exports.ViroFlexView = exports.ViroDirectionalLight = exports.ViroController = exports.ViroCamera = exports.ViroButton = exports.ViroBox = exports.ViroARSceneNavigator = exports.ViroARScene = exports.ViroARPlaneSelector = exports.ViroARPlane = exports.ViroARTrackingTargets = exports.ViroARObjectMarker = exports.ViroARImageMarker = void 0;
exports.ViroRotateStateTypes = exports.ViroPinchStateTypes = exports.ViroClickStateTypes = exports.isARSupportedOnDevice = exports.polarToCartesianActual = exports.polarToCartesian = exports.ViroTrackingStateConstants = exports.ViroRecordingErrorConstants = void 0;
Expand Down
2 changes: 1 addition & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* All rights reserved.
*
*/

import { ViroTelemetry } from "./components/Telemetry";
import { ViroAnimations } from "./components/Animation/ViroAnimations";
import { Viro3DObject } from "./components/Viro3DObject";
import { Viro360Image } from "./components/Viro360Image";
Expand Down
Loading

0 comments on commit 52a330e

Please sign in to comment.