Step 5: Add statistics views to monitor Playlist

Enhance the Playlist application by adding counters to collect statistics.

We will now statistics-gathering components to monitor how often users view the different parts of Playlist.

The page hits will be stored in a table with a special counter data type column. A Cassandra counter column stores numbers that are changed in increments. Counters must be stored in a separate table that consists only of the primary key column and the counter column. Counters need to be implemented this way so Cassandra can coordinate count values across clusters. Updates to a counter need to be replicated to other nodes.

Changes to the Playlist schema 

The statistics will be stored in a new table, statistics, with two columns: counter_name (the primary key) and counter_value of type counter. This structure allows you to define different counters for each page in the application.

The CQL used to create the table is:

CREATE TABLE statistics (counter_name text PRIMARY KEY, counter_value counter);
statistics
counter_name text PK
counter_value counter  

Changes to the Playlist model 

A new model class, playlist.model.StatisticsDAO is used to increment counters that are placed throughout the controller methods of the application. The two methods in StatisticsDAO used to change the counter value are increment_counter and decrement_counter, with the counter name as the parameter.

public static void increment_counter(String counter_name) {

  String queryText = "UPDATE statistics set counter_value = counter_value + 1 where counter_name = ?";
  PreparedStatement preparedStatement = getSession().prepare(queryText);
  BoundStatement boundStatement = preparedStatement.bind(counter_name);
  getSession().execute(boundStatement);

}
public static void decrement_counter(String counter_name) {

  String queryText = "UPDATE statistics set counter_value = counter_value - 1 where counter_name = ?";
  PreparedStatement preparedStatement = getSession().prepare(queryText);
  BoundStatement boundStatement = preparedStatement.bind(counter_name);
  getSession().execute(boundStatement);

}

In our case, the CQL queries increases or decreases the counter by one whenever the increase_counter or decrement_counter methods are called.

Adding counters to the controllers 

Counters are added to the controller servlets to track page hits, users, and playlists. Here is how the home page tracks page views in HomeServlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  StatisticsDAO.increment_counter("page hits: home");

  String javaVersion = System.getProperty("java.version");
  CassandraInfo cassandraInfo = new CassandraInfo();

  request.setAttribute("java_version", javaVersion);
  request.setAttribute("cassandra_info", cassandraInfo);
  getServletContext().getRequestDispatcher("/home.jsp").forward(request,response);

}

The counter name is page hits: home.

In LoginServlet there are counters to log page hits to the login page, failed login attempts, and successful logins.

Viewing the statistics 

All the statistics are viewable by clicking on the Statistics link on the home page. The controller class for the view and model is playlist.controller.StatisticsServlet.

Changes from step 4 

To see all code changes from the step4 branch, enter the following command in a terminal in the playlist directory:

git diff step4..step5