Skip to content

Commit

Permalink
Merge pull request #2 from middleware-labs/mobile-recording-ios
Browse files Browse the repository at this point in the history
feat: ❇️ added initial commit for mobile recording ios
  • Loading branch information
Archish27 committed Mar 4, 2024
2 parents 9037c17 + dbeb4f0 commit 68efc46
Show file tree
Hide file tree
Showing 27 changed files with 1,033 additions and 21 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Middleware React Native Real User Monitoring SDK
- Custom Instrumenation using OpenTelemetry
- Custom logging
- RUM Session Tracking
- Session Recording

## Documentation

Expand Down Expand Up @@ -113,6 +114,34 @@ You can set latitude & longitde as global attributes.
MiddlewareRum.updateLocation(latitude: number, longitude: number)
```

### Enable session recording

By default session recording is enabled, to disable session recording pass `sessionRecording: false` configuration as follows -

```js
const MiddlewareConfig: ReactNativeConfiguration = {
serviceName: 'Mobile-SDK-ReactNative',
projectName: '$Mobile-SDK-ReactNative',
accountKey: '<middleware-account-key>',
target: '<target-url>',
sessionRecording: false,
deploymentEnvironment: 'PROD',
globalAttributes: {
name: '<your-name>',
},
};
```

#### Sanitizing views in session recording

Views will get blurred hiding sensitive information in session recording.

```js
<MiddlewareSanitizedView>
<Component/>
</MiddlewareSanitizedView>
```

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ dependencies {
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation 'io.github.middleware-labs:android-sdk:1.0.8'
implementation 'io.github.middleware-labs:android-sdk:2.0.1'
implementation 'io.opentelemetry.android:instrumentation:+'
implementation 'io.opentelemetry:opentelemetry-sdk:+'
implementation 'io.opentelemetry.semconv:opentelemetry-semconv:+'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public String getServiceName() {
return Keys.SERVICE_NAME.get(map);
}

public String getSessionRecording() {
return Keys.SESSION_RECORDING.get(map);
}

public String getDeploymentEnvironment() {
return Keys.DEPLOYMENT_ENVIRONMENT.get(map);
}
Expand All @@ -39,6 +43,7 @@ private interface Keys {
StringKey ACCOUNT_KEY = new StringKey("accountKey");
StringKey PROJECT_NAME = new StringKey("projectName");
StringKey SERVICE_NAME = new StringKey("serviceName");
StringKey SESSION_RECORDING = new StringKey("sessionRecording");
StringKey DEPLOYMENT_ENVIRONMENT = new StringKey("deploymentEnvironment");
MapKey GLOBAL_ATTRIBUTES = new MapKey("globalAttributes");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public void initialize(ReadableMap configMap, Promise promise) {
final String accountKey = mapReader.getAccountKey();
final String projectName = mapReader.getProjectName();
final String serviceName = mapReader.getServiceName();
final String sessionRecording = mapReader.getSessionRecording();
final String deploymentEnvironment = mapReader.getDeploymentEnvironment();
final ReadableMap globalAttributes = mapReader.getGlobalAttributes();

Expand All @@ -79,7 +80,12 @@ public void initialize(ReadableMap configMap, Promise promise) {
.setGlobalAttributes(attributesFromMap(globalAttributes))
.setDeploymentEnvironment(deploymentEnvironment)
.disableActivityLifecycleMonitoring()
.build((Application) getReactApplicationContext().getApplicationContext().getApplicationContext());
.build(Objects.requireNonNull(getReactApplicationContext().getCurrentActivity()).getApplication());

if("true".equals(sessionRecording)) {
Middleware middleware = Middleware.getInstance();
middleware.startNativeRecording(getCurrentActivity());
}

middlewareSpanExporter = Middleware.getInstance().getMiddlewareRum().getSpanExporter();
WritableMap appStartInfo = Arguments.createMap();
Expand Down Expand Up @@ -162,7 +168,9 @@ public void export(ReadableArray spanMaps, Promise promise) {

@ReactMethod
public void setSessionId(String sessionId) {
Middleware.getInstance().setGlobalAttribute(AttributeKey.stringKey("session.id"), sessionId);
Middleware middleware = Middleware.getInstance();
middleware.setGlobalAttribute(AttributeKey.stringKey("session.id"), sessionId);
middleware.setNativeSessionId(sessionId);
this.nativeSessionId = sessionId;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MiddlewareReactNativePackage implements ReactPackage {
Expand All @@ -23,6 +22,6 @@ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext r
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
return List.of(new NativeSanitizedViewManager());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.middlewarereactnative;

import android.content.Context;
import android.view.ViewGroup;

import io.middleware.android.sdk.Middleware;

public class NativeSanitizedView extends ViewGroup {
public NativeSanitizedView(Context context) {
super(context);
Middleware.getInstance().addSanitizedElement(this);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.middlewarereactnative;

import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;

public class NativeSanitizedViewManager extends ViewGroupManager<ViewGroup> {
@NonNull
@Override
public String getName() {
return "NativeSanitizedView";
}

@NonNull
@Override
protected ViewGroup createViewInstance(@NonNull ThemedReactContext themedReactContext) {
return new NativeSanitizedView(themedReactContext);
}
}
3 changes: 2 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const MiddlewareConfig: ReactNativeConfiguration = {
serviceName: 'Mobile-SDK-iOS',
projectName: 'Mobile-SDK-iOS',
accountKey: '<access-key>',
target: 'https://<targe>',
target: '<target-url>',
sessionRecording: true,
debug: true,
deploymentEnvironment: 'PROD',
globalAttributes: {
Expand Down
18 changes: 12 additions & 6 deletions example/src/Details.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { MiddlewareRum } from '@middleware.io/middleware-react-native';
import {
MiddlewareRum,
MiddlewareSanitizedView,
} from '@middleware.io/middleware-react-native';
import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';

Expand Down Expand Up @@ -46,11 +49,14 @@ export default function Details() {
accessibilityLabel="jsError"
testID="jsError"
/>
<TextInput
style={styles.input}
onChangeText={setCustomUrl}
value={customUrl}
/>
<MiddlewareSanitizedView>
<TextInput
style={styles.input}
onChangeText={setCustomUrl}
value={customUrl}
/>
</MiddlewareSanitizedView>

<Button
title="Fetch custom"
onPress={customFetch}
Expand Down
Loading

0 comments on commit 68efc46

Please sign in to comment.