Removed temporary stats code

This commit is contained in:
felipeal
2012-08-02 18:00:25 +00:00
parent 79adf622d5
commit fc1e641c79
9 changed files with 1 additions and 419 deletions

View File

@@ -23,9 +23,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.jdo.Query; import javax.jdo.Query;
import javax.jdo.annotations.IdentityType; import javax.jdo.annotations.IdentityType;
@@ -90,10 +88,6 @@ public class DeviceInfo {
@Persistent @Persistent
private Date registrationTimestamp; private Date registrationTimestamp;
/**
* Debug is not used anymore, but since the datastore already has it, it is
* now used to flag whether this object has been added to the stats or not.
*/
@Persistent @Persistent
private Boolean debug; private Boolean debug;
@@ -129,7 +123,7 @@ public class DeviceInfo {
return (debug != null ? debug.booleanValue() : false); return (debug != null ? debug.booleanValue() : false);
} }
public void setDebug(Boolean debug) { public void setDebug(boolean debug) {
this.debug = debug; this.debug = debug;
} }

View File

@@ -1,179 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.chrometophone.server;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
/**
* Statistics about a device type.
*/
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class DeviceStats {
private static final Logger log =
Logger.getLogger(DeviceStats.class.getName());
/**
* Device type, as defined on {@link DeviceInfo}.
*/
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@PrimaryKey
private String type;
/**
* Current number of devices using this type.
*/
@Persistent
private int total;
/**
* Total number of devices added for this type.
*/
@Persistent
private int added;
/**
* Current number of devices using this type.
*/
@Persistent
private int deleted;
/**
* Current number of devices converted to this type
*/
@Persistent
private int converted;
private DeviceStats(String type) {
this.type = type;
this.total = this.added = this.deleted = 0;
}
public String getType() {
return type;
}
public int getTotal() {
return total;
}
public int getAdded() {
return added;
}
public int getDeleted() {
return deleted;
}
public int getConverted() {
return converted;
}
@Override
public String toString() {
return String.format("DeviceStats[%s]: total=%d, added=%d, deleted=%d, converted=%d",
type, total, added, deleted, converted);
}
/**
* Queries the stats for a given type.
*/
public static DeviceStats getStats(PersistenceManager pm, String type) {
Query query = pm.newQuery(DeviceStats.class);
DeviceStats stats = null;
Object key = pm.newObjectIdInstance(DeviceStats.class, type);
try {
stats = (DeviceStats) pm.getObjectById(key);
log.log(Level.INFO, "getStats(): {0}", stats);
} catch (JDOObjectNotFoundException e) {
log.log(Level.INFO, "getStats() not found for type {0}", type);
} finally {
query.closeAll();
}
return stats;
}
/**
* Adds one device by a given type.
*/
static DeviceStats addDevice(PersistenceManager pm, String type) {
DeviceStats stats = getStats(pm, type);
stats.total++;
stats.added++;
return stats;
}
/**
* Removes one device by a given type.
*/
static DeviceStats removeDevice(PersistenceManager pm, String type) {
DeviceStats stats = getStats(pm, type);
stats.total--;
stats.deleted++;
return stats;
}
/**
* Converts one device by a given type.
*/
static DeviceStats convertsDevice(PersistenceManager pm, String type, int size) {
log.log(Level.INFO, "Updating entity of type {0} with {1} conversions",
new Object[] {type, size});
DeviceStats stats = getStats(pm, type);
stats.total += size;
stats.converted += size;
return stats;
}
static List<DeviceStats> getAll(PersistenceManager pm) {
Query query = pm.newQuery(DeviceStats.class);
@SuppressWarnings("unchecked")
List<DeviceStats> allStats = (List<DeviceStats>) query.execute();
return allStats;
}
/**
* Create initial objects.
*/
static void init(PersistenceManager pm) {
for (String type : DeviceInfo.SUPPORTED_TYPES) {
add(pm, type);
}
}
private static void add(PersistenceManager pm, String type) {
DeviceStats stats = getStats(pm, type);
if (stats == null) {
stats = new DeviceStats(type);
log.log(Level.INFO, "Creating {0} entity for type {1}",
new Object[] {DeviceStats.class.getSimpleName(), type});
pm.makePersistent(stats);
}
}
}

View File

@@ -166,7 +166,6 @@ public class RegisterServlet extends HttpServlet {
// TODO: only need to write if something changed, for chrome nothing // TODO: only need to write if something changed, for chrome nothing
// changes, we just create a new channel // changes, we just create a new channel
pm.makePersistent(device); pm.makePersistent(device);
DeviceStats.addDevice(pm, deviceType);
log.log(Level.INFO, "Registered device " + reqInfo.userName + " " + log.log(Level.INFO, "Registered device " + reqInfo.userName + " " +
deviceType); deviceType);

View File

@@ -224,7 +224,6 @@ public class RequestInfo {
DeviceInfo deviceInfo = registrations.get(i); DeviceInfo deviceInfo = registrations.get(i);
if (deviceInfo.getDeviceRegistrationID().equals(regId)) { if (deviceInfo.getDeviceRegistrationID().equals(regId)) {
pm.deletePersistent(deviceInfo); pm.deletePersistent(deviceInfo);
DeviceStats.removeDevice(pm, type);
// Keep looping in case of duplicates // Keep looping in case of duplicates
} }
} }

View File

@@ -21,7 +21,6 @@ import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message; import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Message.Builder; import com.google.android.gcm.server.Message.Builder;
import com.google.android.gcm.server.Result; import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.google.appengine.api.channel.ChannelMessage; import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelServiceFactory; import com.google.appengine.api.channel.ChannelServiceFactory;

View File

@@ -24,17 +24,14 @@ import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManager;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.chrometophone.server;
import com.google.android.c2dm.server.C2DMessaging;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Adds devices whose debug field is not set to the stats, and update the field.
*/
public class StatsConversionServlet extends HttpServlet {
private static final int MAX_ROWS = 500;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException{
ServletContext ctx = getServletContext();
List<DeviceInfo> devices = null;
PersistenceManager pm = C2DMessaging.getPMF(ctx).getPersistenceManager();
Map<String, Integer> conversionsByType = new HashMap<String, Integer>();
try {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<head>");
out.println("<title>Device stats conversion</title>");
out.println("</head>");
out.println("<body>");
int total = 0;
do {
Query query = pm.newQuery(DeviceInfo.class);
query.setFilter("debug == null");
query.setRange(0, MAX_ROWS);
@SuppressWarnings("unchecked")
List<DeviceInfo> uncastDevices = (List<DeviceInfo>) query.execute();
devices = uncastDevices;
if (devices.isEmpty()) {
out.println("<p>No devices need conversion</p>");
} else {
int size = devices.size();
total += size;
out.println("<p>Converting " + size + " devices...");
out.flush();
for (DeviceInfo device : devices) {
device.setDebug(true);
pm.currentTransaction().begin();
pm.makePersistent(device);
pm.currentTransaction().commit();
String type = device.getType();
Integer converted = conversionsByType.get(type);
if (converted == null) {
converted = 1;
} else {
converted ++;
}
conversionsByType.put(type, converted);
}
}
query.closeAll();
flushStats(pm, conversionsByType);
out.println(total + " converted so far.</p>");
} while (devices != null && ! devices.isEmpty());
out.println("</body></html>");
} finally {
pm.close();
}
resp.setStatus(HttpServletResponse.SC_OK);
}
private void flushStats(PersistenceManager pm, Map<String, Integer> conversionsByType) {
for (Entry<String, Integer> entry : conversionsByType.entrySet()) {
String type = entry.getKey();
int size = entry.getValue();
DeviceStats stats = DeviceStats.convertsDevice(pm, type, size);
pm.currentTransaction().begin();
pm.makePersistent(stats);
pm.currentTransaction().commit();
}
conversionsByType.clear();
}
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.chrometophone.server;
import com.google.android.c2dm.server.C2DMessaging;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Shows the statistics of how many devices use C2DM or GCM.
*
* Useful for debugging purposes.
*/
public class StatsServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException{
ServletContext ctx = getServletContext();
List<DeviceStats> allStats;
PersistenceManager pm = C2DMessaging.getPMF(ctx).getPersistenceManager();
try {
DeviceStats.init(pm);
allStats = DeviceStats.getAll(pm);
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html><body>");
out.println("<head>");
out.println("<title>Device stats</title>");
out.println("</head>");
out.println("<body>");
out.println("<h3>Device stats</h3>");
if (allStats.isEmpty()) {
out.println("<p>No devices registered yet!</p>");
} else {
int total = 0;
int added = 0;
int deleted = 0;
int converted = 0;
for (DeviceStats stats: allStats) {
total += stats.getTotal();
added += stats.getAdded();
deleted += stats.getDeleted();
converted += stats.getConverted();
}
out.println("<table cellspacing='2' cellpadding='2'><tr><th>Type</th>" +
"<th>Added</th><th>Deleted</th><th>Converted</th><th>Total</th><th>Share</th></tr>");
for (DeviceStats stats: allStats) {
int count = stats.getTotal();
float share = (total == 0) ? 0 : (100 * count) / total;
out.println("<tr>" +
"<td align='right'>" + stats.getType() + "</td>" +
"<td align='right'>" + stats.getAdded() + "</td>" +
"<td align='right'>" + stats.getDeleted() + "</td>" +
"<td align='right'>" + stats.getConverted() + "</td>" +
"<td align='right'>" + count + "</td>" +
"<td align='right'>" + share + "%</td></tr>");
}
out.println("<tr>" +
"<td align='right'>Total</td>" +
"<td align='right'>" + added + "</td>" +
"<td align='right'>" + deleted + "</td>" +
"<td align='right'>" + converted + "</td>" +
"<td align='right'>" + total + "</td>" +
"<td align='right'>100.0%</td></tr>");
out.println("</table>");
}
out.println("</body></html>");
} finally {
pm.close();
}
resp.setStatus(HttpServletResponse.SC_OK);
}
}

View File

@@ -61,18 +61,6 @@
</servlet-class> </servlet-class>
</servlet> </servlet>
<servlet>
<servlet-name>StatsServlet</servlet-name>
<servlet-class>com.google.android.chrometophone.server.StatsServlet
</servlet-class>
</servlet>
<servlet>
<servlet-name>StatsConversionServlet</servlet-name>
<servlet-class>com.google.android.chrometophone.server.StatsConversionServlet
</servlet-class>
</servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>RegisterServlet</servlet-name> <servlet-name>RegisterServlet</servlet-name>
<url-pattern>/register</url-pattern> <url-pattern>/register</url-pattern>
@@ -113,16 +101,6 @@
<url-pattern>/admin/sender</url-pattern> <url-pattern>/admin/sender</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>StatsServlet</servlet-name>
<url-pattern>/admin/stats</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>StatsConversionServlet</servlet-name>
<url-pattern>/admin/convertStats</url-pattern>
</servlet-mapping>
<security-constraint> <security-constraint>
<web-resource-collection> <web-resource-collection>
<web-resource-name>admin</web-resource-name> <web-resource-name>admin</web-resource-name>