Skip to content

Commit

Permalink
Merge branch 'main' into custom_item
Browse files Browse the repository at this point in the history
  • Loading branch information
zhu-xiaowei authored Oct 13, 2023
2 parents 82f3f23 + f74a4c9 commit 0c2a86c
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 72 deletions.
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Add the following dependency to your `app` module's `build.gradle` file.

```groovy
dependencies {
implementation 'software.aws.solution:clickstream:0.8.0'
implementation 'software.aws.solution:clickstream:0.9.0'
}
```

Expand Down Expand Up @@ -62,7 +62,7 @@ Your `appId` and `endpoint` are already set up in it, here's an explanation of e

**3.Initialize the SDK**

Please Initialize the SDK in the Application `onCreate()` method.
It is recommended that you initialize the SDK in the Application `onCreate()` method. Please note that the initialization code needs to run in the main thread.

```java
import software.aws.solution.clickstream.ClickstreamAnalytics;
Expand Down Expand Up @@ -228,10 +228,26 @@ If you want to use custom DNS for network request, you can create your `CustomOk
#### Send event immediately

```java
import software.aws.solution.clickstream.ClickstreamAnalytics;

// for send event immediately.
ClickstreamAnalytics.flushEvent();
```

#### Disable SDK
You can disable the SDK in the scenario you need. After disabling the SDK, the SDK will not handle the logging and sending of any events. Of course you can enable the SDK when you need to continue logging events.

Please note that the disable and enable code needs to be run in the main thread.
```java
import software.aws.solution.clickstream.ClickstreamAnalytics;

// disable SDK
ClickstreamAnalytics.disable();

// enable SDK
ClickstreamAnalytics.enable();
```

## How to build locally

open an terminal window, at the root project folder to execute:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public final class AWSClickstreamPlugin extends AnalyticsPlugin<Object> {
private AnalyticsClient analyticsClient;
private AutoEventSubmitter autoEventSubmitter;
private ActivityLifecycleManager activityLifecycleManager;
private ClickstreamManager clickstreamManager;
private boolean isEnable = true;

/**
* Constructs a new {@link AWSClickstreamPlugin}.
Expand Down Expand Up @@ -76,15 +78,25 @@ public void identifyUser(@NonNull String userId, @Nullable UserProfile profile)
}

@Override
public void disable() {
autoEventSubmitter.stop();
activityLifecycleManager.stopLifecycleTracking(context);
public synchronized void disable() {
if (isEnable) {
autoEventSubmitter.stop();
activityLifecycleManager.stopLifecycleTracking(context, ProcessLifecycleOwner.get().getLifecycle());
clickstreamManager.disableTrackAppException();
isEnable = false;
LOG.info("Clickstream SDK disabled");
}
}

@Override
public void enable() {
autoEventSubmitter.start();
activityLifecycleManager.startLifecycleTracking(context, ProcessLifecycleOwner.get().getLifecycle());
public synchronized void enable() {
if (!isEnable) {
autoEventSubmitter.start();
activityLifecycleManager.startLifecycleTracking(context, ProcessLifecycleOwner.get().getLifecycle());
clickstreamManager.enableTrackAppException();
isEnable = true;
LOG.info("Clickstream SDK enabled");
}
}

@Override
Expand Down Expand Up @@ -184,7 +196,7 @@ public void configure(
}

AWSClickstreamPluginConfiguration clickstreamPluginConfiguration = configurationBuilder.build();
ClickstreamManager clickstreamManager = ClickstreamManagerFactory.create(
clickstreamManager = ClickstreamManagerFactory.create(
context,
clickstreamPluginConfiguration
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ void startLifecycleTracking(final Context context, Lifecycle lifecycle) {
}
}

void stopLifecycleTracking(final Context context) {
void stopLifecycleTracking(final Context context, Lifecycle lifecycle) {
if (context instanceof Application) {
((Application) context).unregisterActivityLifecycleCallbacks(this);
lifecycle.removeObserver(this);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@
import com.amplifyframework.AmplifyException;
import com.amplifyframework.core.Amplify;

import com.amazonaws.logging.Log;
import com.amazonaws.logging.LogFactory;
import software.aws.solution.clickstream.client.AnalyticsClient;
import software.aws.solution.clickstream.client.ClickstreamConfiguration;
import software.aws.solution.clickstream.client.Event;
import software.aws.solution.clickstream.client.util.ThreadUtil;

/**
* This is the top-level customer-facing interface to The ClickstreamAnalytics.
*/
public final class ClickstreamAnalytics {
private static final Log LOG = LogFactory.getLog(ClickstreamAnalytics.class);

private ClickstreamAnalytics() {
throw new UnsupportedOperationException("No instances allowed.");
Expand All @@ -41,6 +45,9 @@ private ClickstreamAnalytics() {
* @throws AmplifyException Exception of init.
*/
public static void init(@NonNull Context context) throws AmplifyException {
if (ThreadUtil.notInMainThread()) {
throw new AmplifyException("Clickstream SDK initialization failed", "Please initialize in the main thread");
}
Amplify.addPlugin(new AWSClickstreamPlugin(context));
Amplify.configure(context);
}
Expand Down Expand Up @@ -71,7 +78,7 @@ public static void flushEvents() {
}

/**
* add user clickstreamAttribute.
* Add user clickstreamAttribute.
*
* @param clickstreamAttribute the global clickstreamAttribute.
*/
Expand All @@ -80,7 +87,7 @@ public static void addGlobalAttributes(ClickstreamAttribute clickstreamAttribute
}

/**
* delete global attributes.
* Delete global attributes.
*
* @param attributeName the attribute name to delete.
*/
Expand All @@ -89,7 +96,7 @@ public static void deleteGlobalAttributes(@NonNull String... attributeName) {
}

/**
* add user attributes.
* Add user attributes.
*
* @param userProfile user
*/
Expand All @@ -98,7 +105,7 @@ public static void addUserAttributes(ClickstreamUserAttribute userProfile) {
}

/**
* set user id.
* Set user id.
*
* @param userId user
*/
Expand All @@ -111,7 +118,29 @@ public static void setUserId(String userId) {
}

/**
* get clickstream configuration
* Enable clickstream SDK.
*/
public static void enable() {
if (ThreadUtil.notInMainThread()) {
LOG.error("Clickstream SDK enabled failed, please execute in the main thread");
return;
}
Amplify.Analytics.enable();
}

/**
* Disable clickstream SDK.
*/
public static void disable() {
if (ThreadUtil.notInMainThread()) {
LOG.error("Clickstream SDK disabled failed, please execute in the main thread");
return;
}
Amplify.Analytics.disable();
}

/**
* Get clickstream configuration
* please config it after initialize.
*
* @return ClickstreamConfiguration configurationF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,41 @@ public final class ClickstreamExceptionHandler implements Thread.UncaughtExcepti
private static final Log LOG = LogFactory.getLog(ClickstreamExceptionHandler.class);
private static ClickstreamExceptionHandler handlerInstance;
private static final int SLEEP_TIMEOUT_MS = 500;
private final Thread.UncaughtExceptionHandler defaultExceptionHandler;
private ClickstreamContext clickstreamContext;
private Thread.UncaughtExceptionHandler defaultExceptionHandler;
private final ClickstreamContext clickstreamContext;

private ClickstreamExceptionHandler() {
private ClickstreamExceptionHandler(ClickstreamContext context) {
this.clickstreamContext = context;
}

/**
* start listening the exception events.
*/
public void startTrackException() {
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}

/**
* stop listening the exception events.
*/
public void stopTackException() {
Thread.setDefaultUncaughtExceptionHandler(null);
}

/**
* init static method for ClickstreamExceptionHandler.
*
* @param context the clickstream context for initial the ClickstreamExceptionHandler
* @return ClickstreamExceptionHandler the instance.
*/
public static synchronized ClickstreamExceptionHandler init() {
public static synchronized ClickstreamExceptionHandler init(ClickstreamContext context) {
if (handlerInstance == null) {
handlerInstance = new ClickstreamExceptionHandler();
handlerInstance = new ClickstreamExceptionHandler(context);
}
return handlerInstance;
}

/**
* setter for clickstreamContext.
*
* @param context ClickstreamContext
*/
public void setClickstreamContext(ClickstreamContext context) {
this.clickstreamContext = context;
}

/**
* fetch uncaught exception and record crash event.
*
Expand All @@ -69,32 +75,35 @@ public void setClickstreamContext(ClickstreamContext context) {
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
try {
String exceptionMessage = "";
String exceptionStack = "";
try {
if (throwable.getMessage() != null) {
exceptionMessage = throwable.getMessage();
}
final Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
throwable.printStackTrace(printWriter);
Throwable cause = throwable.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
if (clickstreamContext.getClickstreamConfiguration().isTrackAppExceptionEvents()) {
String exceptionMessage = "";
String exceptionStack = "";
try {
if (throwable.getMessage() != null) {
exceptionMessage = throwable.getMessage();
}
final Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
throwable.printStackTrace(printWriter);
Throwable cause = throwable.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
exceptionStack = writer.toString();
} catch (Exception exception) {
LOG.error("exception for get exception stack:", exception);
}
printWriter.close();
exceptionStack = writer.toString();
} catch (Exception exception) {
LOG.error("exception for get exception stack:", exception);
}

final AnalyticsEvent event =
this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.APP_EXCEPTION);
event.addInternalAttribute("exception_message", exceptionMessage);
event.addInternalAttribute("exception_stack", exceptionStack);
this.clickstreamContext.getAnalyticsClient().recordEvent(event);
final AnalyticsEvent event =
this.clickstreamContext.getAnalyticsClient().createEvent(Event.PresetEvent.APP_EXCEPTION);
event.addInternalAttribute("exception_message", exceptionMessage);
event.addInternalAttribute("exception_stack", exceptionStack);
this.clickstreamContext.getAnalyticsClient().recordEvent(event);
}

this.clickstreamContext.getAnalyticsClient().submitEvents();
try {
Thread.sleep(SLEEP_TIMEOUT_MS);
} catch (InterruptedException exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class ClickstreamManager {
private final AnalyticsClient analyticsClient;
private final SessionClient sessionClient;
private final AutoRecordEventClient autoRecordEventClient;
private ClickstreamExceptionHandler exceptionHandler;

/**
* Constructor.
Expand All @@ -57,6 +58,7 @@ public ClickstreamManager(@NonNull final ClickstreamConfiguration config) {
this.autoRecordEventClient = new AutoRecordEventClient(this.clickstreamContext);
this.clickstreamContext.setSessionClient(this.sessionClient);
if (config.isTrackAppExceptionEvents()) {
exceptionHandler = ClickstreamExceptionHandler.init(this.clickstreamContext);
enableTrackAppException();
}
LOG.debug(String.format(Locale.US,
Expand All @@ -68,9 +70,22 @@ public ClickstreamManager(@NonNull final ClickstreamConfiguration config) {
}
}

private void enableTrackAppException() {
ClickstreamExceptionHandler handler = ClickstreamExceptionHandler.init();
handler.setClickstreamContext(this.clickstreamContext);
/**
* Enable track app exception.
*/
public void enableTrackAppException() {
if (exceptionHandler != null) {
exceptionHandler.startTrackException();
}
}

/**
* Disable track app exception.
*/
public void disableTrackAppException() {
if (exceptionHandler != null) {
exceptionHandler.stopTackException();
}
}

/**
Expand Down
Loading

0 comments on commit 0c2a86c

Please sign in to comment.