Snowplow Java Tracker 0.4.0 released

Share

We’re excited to announce another release of the Snowplow Java Tracker version 0.4.0.

This release makes some significant updates to the Java Tracker. The main objective for this release was to bring the Tracker much closer in functional terms to the Python Tracker. In doing so, we’ve added new Emitter, TrackerPayload and Subject classes along with various changes to the existing Tracker class.

Some of the other more notable features in this release is support for POST requests, sending of events asynchronous and event queueing. I’ll be covering everything mentioned above in more detail:

  1. Structural improvements
  2. The Emitter class
  3. The TrackerPayload class
  4. The Subject class
  5. Google Guava Preconditions
  6. Tracker class constructor
  7. Optional context and timestamp
  8. Miscellaneous
  9. Support

1. Structural improvements

It’s important to first mention the structural changes that have come with this release, since using this version breaks compatibility with older versions of the Tracker. Here is a list of the changes made:

2. The Emitter class

Emitter lets you create multiple instances of it so you can send events to many collectors if you want. The Emitter class supports sending event data via GET or POST requests although note that Snowplow will only be supporting POST data in a future release. This can be set using the HttpMethod enum.

Events by default are buffered until they reach 10 events and are then sent in a batch. We now support sending events either in a batch or instantly upon being tracked. BufferOption is used to let you switch between the two options.

You can also now choose whether events should be sent asynchronously, using the RequestMethod enum.

The Emitter by default, sends events synchronously, using GET requests and with a buffer size of 10 events.

Here you can find an example of all the options available:

import com.snowplowanalytics.snowplow.tracker.Emitter<span class="o">; import com.snowplowanalytics.snowplow.tracker.Subject<span class="o">; import com.snowplowanalytics.snowplow.tracker.Tracker<span class="o">; import com.snowplowanalytics.snowplow.tracker.emitter.HttpMethod<span class="o">; import com.snowplowanalytics.snowplow.tracker.emitter.BufferOption<span class="o">; import com.snowplowanalytics.snowplow.tracker.emitter.RequestMethod<span class="o">; public static void main(String[] args) { // Create a simple emitter which sends events to d3rkrsqld9gmqf.cloudfront.net Emitter emitter1 = new Emitter("d3rkrsqld9gmqf.cloudfront.net"<span class="o">); // You can create an Emitter with the HTTP method of choice // Here, we are changing emitter2 to send events as POST requests Emitter emitter2 = new Emitter("d3rkrsqld9gmqf.cloudfront.net", HttpMethod.POST<span class="o">); // If want to send events immediately, we set the buffer accordingly emitter1.setBufferOption(BufferOption.Instant) // You can choose to have emitter 2 send events asynchronously emitter2.setRequestMethod(RequestMethod.Asynchronous<span class="o">); // Create a tracker instance using the two emitters Tracker tracker1 = new Tracker(emitter1, "cf", "CF63A"<span class="o">); Tracker tracker2 = new Tracker(emitter2, "cf", "CF63A"<span class="o">); // Track the user viewing the page which is sent via emitter1 tracker1.trackPageView("www.example.com", "Hello, world!", "www.snowplowanalytics.com"<span cl
ass="o">); // Track the user viewing the screen which is sent via emitter2 tracker2.trackScreenView("Main Screen", "a8shnw7"<span class="o">); }

3. The TrackerPayload class

The TrackerPayload class implements the new Payload interface. It lets you create a Payload similar to a HashMap but made specifically for tracking events.

Currently, it’s used by the Tracker class to create each tracking payload, but in the next release, we’ll add the ability to add your own Payload into an Unstructured Tracking Event.

4. The Subject class

The Subject class functions similar to its Python counterpart: an instance of the Subject class represents a user who is performing an event in the SubjectVerbDirect Object model proposed in our Snowplow event grammar. Although you can create a Tracker instance without a Subject, you won’t be able to add information such as user ID and timezone to your events without one.

Here’s an example that shows you how to track more that one user using the Subject class:

import com.snowplowanalytics.snowplow.tracker.Emitter<span class="o">; import com.snowplowanalytics.snowplow.tracker.Subject<span class="o">; import com.snowplowanalytics.snowplow.tracker.Tracker<span class="o">; import com.snowplowanalytics.snowplow.tracker.DevicePlatform<span class="o">; public static void main(String[] args) { // Create a simple emitter which sends events to d3rkrsqld9gmqf.cloudfront.net Emitter emitter = new Emitter("d3rkrsqld9gmqf.cloudfront.net"<span class="o">); // Create a Subject Subject subject1 = new Subject<span class="o">(); // Set the Platform using the DevicePlatform enum subject1.setPlatform(DevicePlatform.ConnectedTV<span class="o">); // Set the user id and screen resolution as well if you want subject1.setUserId("0a78f2867de"<span class="o">); subject1.setScreenResolution(1920, 1080<span class="o">); // Create a tracker instance using the Emitter you created Tracker tracker = new Tracker(emitter, "cf", "CF63A"<span class="o">); // Set the subject you created tracker.setSubject(subject1<span class="o">); // Track the user view the page tracker.trackPageView("www.example.com", "Hello, world!", "www.snowplowanalytics.com"<span class="o">); // Create another Subject instance corresponding to a mobile user Subject subject2 = new Subject<span class="o">(); subject.setPlatform(DevicePlatform.Mobile<span class="o">); subject.setUserId("0b08f8be3f1"<span class="o">); // Change the tracker subject from subject1 to subject2 // All events fired will have instead have information we set about subject2 attached tracker.setSubject(subject2<span class="o">); // Tracker user subject2 viewing a page tracker.trackPageView("www.example.com", "Hello, world!", "www.snowplowanalytics.com"<span class="o">); }

It is also possible to set the subject during Tracker initialization:

Tracker tracker = new Tracker(emitter, subject, "cf", "CF63A"<span class="o">);

5. Google Guava Preconditions

We’ve removed the ContractManager class and replaced it with Google’s Precondition check. We check to make sure that trackers are not sending null or empty string parameters when tracking events.

For example, if were to track a page view without setting the pageUrl:

tracker.trackPageView("", "My Page", "www.example.com"<span class="o">);

We would see an exception sent:

java.lang.IllegalArgumentException: pageUrl cannot be empty at com.google.common.base.Preconditions.checkArgument(Preconditions.java:125) at com.snowplowanalytics.snowplow.tracker.Tracker.trackPageView(Tracker.java:114) at com.snowplowanalytics.snowplow.tracker.TrackerTest.testTrackPageView3(TrackerTest.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

6. Tracker class constructor

In the Tracker class, you’ve seen the examples from the previous posts where we’ve changed the Tracker constructor. To formally mention the changes, we now provide four options for the Tracker constructor:

// Defaults encoding to true, without setting a Subject public Tracker(Emitter emitter, String namespace, String appId) // Defaults encoding to true, and lets you pass in a Subject public Tracker(Emitter emitter, Subject subject, String namespace, String appId) // Defaults to not using a Subject public Tracker(Emitter emitter, String namespace, String appId, boolean base64Encoded<span class="o">); // Everything can be set during the initial construction public Tracker(Emitter emitter, Subject subject, String namespace, String appId, boolean base64Encoded)

Under the hood, the way we construct each specific tracking event is done within tracker class. Previously, the PayloadC class would handle this.

7. Optional context and timestamp

Similar to the Tracker constructor, we wanted to make it optional for you to set certain parameters without any magic numbers or null values involved.

Each Tracker now has multiple method signatures letting you send a context and/or timestamp depending on your own needs. Here are the method signatures:

// Default created timestamp with no context public void trackPageView(String pageUrl, String pageTitle, String referrer) // Default created timestamp with no context public void trackPageView(String pageUrl, String pageTitle, String referrer, Map context) // You pass in your own timestamp with no context passed public void trackPageView(String pageUrl, String pageTitle, String referrer, double timestamp) // You can pass the timestamp and context you want public void trackPageView(String pageUrl, String pageTitle, String referrer, Map context, double timestamp)

The TransactionItem class also has a method signature for an optional context as well:

public TransactionItem (String order_id, String sku, double price, int quantity, String name, String category, String currency<span class="o">);

8. Miscellaneous

With the new classes being created, we’ve also added more unit tests to verify them. Have a look at some of them for more examples on how they are being used.

The Constant and Parameter classes have both been updated to support all the tracking parameters that would be used. This will be more useful when you start creating your own Payload instances.

9. Support

Please get in touch if you need help setting up the Snowplow Java Tracker or want to suggest a new feature. The Snowplow Java Tracker is rapidly evolving, so please feel free to raise an issue if you find any bugs or have any feature requests.

For more details on this release, please check out the 0.4.0 Release Notes on GitHub.

Share

Related articles