How to get Worklight 6.1 Analytics custom events working on iOS/Android/mobileWeb?

318 views Asked by At

I am having major issues getting Worklight Analytics custom events working (WL v6.1).

For my environment, I'm on the latest 6.1.0.1 (0718). We have installed Analytics on an AWS instance for development and I'm pointing to it via worklight.properties. The operational analytics dashboard is accessible and is showing correct basic analytics data.

I have problems across mobileWeb (using this for dev only), iPhone, and Android environments.

mobileWeb: analytics queue size increases forever and never triggers a send. I ran through the code in firebug and it appears to use the deprecated WL.Client.isConnected() method which always returns false for mobileWeb. So I hacked this to return true and was able to get mobileWeb working properly: queue is flushed after 10 messages and the result can be viewed in the Analytics console server log. This confirms that the analytics server is configured properly at least.

iPhone simulator: attempts to send after 10 messages have been queued. However I get a 400 from IHS on the analytics server. I have tried increasing the log level but was unable to produce anything more:

<wl_server_ip> - - [11/Aug/2014:13:12:42 -0400] "POST /iwap/v1/events/_bulk HTTP/1.1" 400 335

Android emulator: I see a TeaLeaf exception when the analytics send is called (after queuing 10 messages):

08-11 13:32:16.970: E/UICAndroid(1748): TL Library Error: url:http://<analytics_ip>:80/iwap/v1/events/_bulk stream errorjava.util.zip.DataFormatException: stream error
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.zip.Deflater.deflateImpl(Native Method)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.zip.Deflater.deflateImpl(Deflater.java:241)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.zip.Deflater.deflate(Deflater.java:232)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.zip.DeflaterOutputStream.flush(DeflaterOutputStream.java:193)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.HTTPUtil.createEntity(HTTPUtil.java:93)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.HTTPUtil.sendPost(HTTPUtil.java:181)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.HTTPUtil.sendHttpPost(HTTPUtil.java:115)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.PostTask.sendMessageFormat(PostTask.java:72)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.PostTask.doInBackground(PostTask.java:28)
08-11 13:32:16.970: E/UICAndroid(1748):     at com.tl.uic.util.PostTask.doInBackground(PostTask.java:1)
08-11 13:32:16.970: E/UICAndroid(1748):     at android.os.AsyncTask$2.call(AsyncTask.java:288)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-11 13:32:16.970: E/UICAndroid(1748):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-11 13:32:16.970: E/UICAndroid(1748):     at java.lang.Thread.run(Thread.java:841)

Here's the very basic analytics call, essentially a cut/paste from the WL 6.1 InfoCenter:

function doBetterAnalyticsWork(i) {
        WL.Analytics.log({hello: 'world ' + i}, 'test-analytics')
        .always(function(wasQueueFlushed, errObj){
            if (wasQueueFlushed) {
                WL.Logger.debug('The queue was flushed');
            } else {
                WL.Logger.debug('The queue was NOT flushed');
            }
            if (typeof errObj === 'object') {
                WL.Logger.error('Error trying to flush the queue', errObj);
            }
        });
        WL.Logger.debug('WL.Analytics.state(): ' + JSON.stringify(WL.Analytics.state()));
    }

I iterate over this 10 times in a for loop in order to trigger the analytics send. Incidentally, I never get the "The queue was flushed" message but it seems to at least attempt a send on iPhone/Android.

Any help would be much appreciated. I can provide more info as-needed.

2

There are 2 answers

2
mikerott On BEST ANSWER

mobileWeb: I will followup on the necessity to avoid using WL.Client.isConnected

iOS: jnortey is correct; the client should not be aware of the URL of the analytics server. If, at some point, you had the address in the TLFConfigurableItems.plist file, ran your app, then replaced the value in TLFConfigurableItems.plist with @USE_WORKLIGHT_DEFAULT@, the old hard-coded value may have persisted, and you should uninstall/reinstall the app or clear all data and try again.

Android: Same story as iOS. If the TLFConfigurableItems.properties file was used with a hard-coded value, that value has persisted, and you'll need to uninstall/reinstall the app, or clear all data and try again.

Also, what version of Android are you testing? Kitkat changed the DeflaterOutputStream behavior such that if you call flush() after finish() an exception is thrown. The version of the Tealeaf library you have probably does exactly this, and therefore you need a newer fixed version of the Tealeaf library on Android to accommodate the change in Android's DeflaterOutputStream behavior.

7
jnortey On

Edit:

After I second look I see another issue:

TL Library Error: url:http://:80/iwap/v1/events/_bulk stream errorjava.util.zip.DataFormatException: stream error

and

- - [11/Aug/2014:13:12:42 -0400] "POST /iwap/v1/events/_bulk HTTP/1.1" 400 335

Are your clients sending data directly to "/iwap/v1/events/_bulk"? The client data should never go directly to the analytics server. It must go through the worklight server and then the worklight server will forward it to the analytics server. Have you configured your client code to point to "/iwap/v1/events/_bulk"? If you remove this configuration, it should default to the correct location that points to the worklight server.

Original:

In Worklight 6.1, Worklight uses Tealeaf under the covers to collect and send analytics data. When the analytics data is sent to Tealeaf in a loop, it fails for some reason. Instead of making the calls in a loop, try manually making the call to WL.Analytics.log by using a button.