Skip to content
Arnaud PICHERY edited this page Oct 19, 2018 · 1 revision

Additionally to storing the tracked events, it is possible to plug custom code in the WT1 Web backend. The custom code receives all events, like the storage processor, and can handle them as required.

Major use cases include:

  • forwarding the events to another tracking backend;
  • real-time analysis services;
  • integration into third-party entreprise systems like message queues

There can be several handlers, each with its own class and parameters.

Processing of the events by the handlers is asynchronous. Each handler runs in its own thread and receives the event through an independent queue. This guarantees that a slow handler does not negatively impacts other handler.

Assuming that the handler is able to keep up with the incoming flow, the latency between the time when an event is initially received from the client and when it arrives at the handler is typically in the low milliseconds range.

Handlers are without delivery guarantee: if a handler cannot keep up with the incoming flow (for example if the remote service is slow or down), the queue will fill up. Once it reaches a configurable threshold, events start being dropped to avoid a memory overrun.

Configuration

Event handlers are configured in the config.properties file.

Each handler has all its parameters within the handler.X key, where X is the index of the handler.

The Java class to use for a handler is specified in the handler.X.class parameter.

Specific configuration for each handler must be put in handler.X.params.PARAMNAME parameter. The available PARAMNAMEs depend on the handler.

For example, the following configuration declares two handlers:

handler.0.class=com.mycompany.wt1.MyFirstHandler
handler.0.params.paramA=valueA
handler.0.params.paramB=valueB
handler.1.class=com.mycompany.wt1.MySecondHandler
handler.1.params.anotherParam=anotherValue

Standard handlers

Several handlers are provided in the WT1 distribution:

  • CounterHandler, which does countings and aggregations on the event flow. The goal of this CounterHandler is to provide real-time insights into the events flow, additionally to the insights provided by the debug API.
  • None other yet.

Developing a custom handler

To develop a custom handler, you must implement the following Java interface:

/**
 * Base processor for tracked requests.
 * All methods of this processor are called in a single thread.
 */
public interface TrackingRequestProcessor {
    /**
     * Called to initialize the processor.
     * @param processorParams the dictionary of parameters found in the configuration file as a key-value map.
     */
    public void init(Map<String, String> processorParams) throws IOException;
 
    /**
     * Process one request
     */
    public void process(TrackedRequest req) throws IOException;
 
    /**
     * Called when the system is shutting down. The processor must flush all
     * pending events and IOs.
     */
    public void shutdown() throws IOException;
}

The received object has the following members:

/**
 * Model object for one tracking event.
 */
public class TrackedRequest {
    /** IP address of the visitor */
    public String origAddress;
    /** Value of the visitor id */
    public String visitorCookieValue;
    /** Value of the visitor params, encoded as an HTTP query string */
    public String visitorParamsCookieValue;
    /** Value of the sesion params, encoded as an HTTP query string */
    public String sessionParamsCookieValue;
 
    /** URL of the page from which the tracking event originated */
    public String page;
    /** HTTP referer of the page from which the tracking event originated */
    public String referer;
 
    /** Timezone offset of the visitor, in minutes from UTC */
    public String tzOffset;
 
    /** Width in pixels of the visitor's browser window */
    public int browserWidth;
    /** Heightin pixels of the visitor's browser window */
    public int browserHeight;
    /** Width in pixels of the visitor's screen */
    public int screenWidth;
    /** Height in pixels of the visitor's screen */
    public int screenHeight;
    /** User-Agent of the visitor's browser */
    public String ua;
    /** Language of the visitor's browser */
    public String browserLanguage;
 
    /** Type of the event (generally "page" or "event") */
    public String type;
 
    /** Timestamp at which the event was received on the backend */
    public long now = System.currentTimeMillis();
 
    /** Custom Parameters of the event, encoded as an HTTP query string */
    public String eventParams;
}