Here’s the entire source code for my http provider, in it’s current state. To install it, compile it and put the .jar into the Wowza lib folder. Then add the following into VHost.xml, in the admin HostPort.HTTPProviders section:
<HTTPProvider>
<BaseClass>tv.epresence.wms.AccessLogProvider</BaseClass>
<RequestFilters>accesslogs*</RequestFilters>
<AuthenticationMethod>admin-digest</AuthenticationMethod>
</HTTPProvider>
Add the path to the logs folder in the VHost.Properties section:
<Property>
<Name>rootLogPath</Name>
<Value>/usr/local/WowzaMediaServer/logs</Value>
</Property>
AccessLogProvider.java:
package tv.epresence.wms;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.text.*;
import java.util.regex.*;
import com.wowza.wms.vhost.*;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
public class AccessLogProvider extends HTTProvider2Base {
public static WMSLogger log;
static {
log = WMSLoggerFactory.getLogger(null);
}
private AccessLogRequest parseRequestParameters(IHTTPRequest req) {
Date startDate;
Date endDate;
String yearParam = req.getParameter("year");
String monthParam = req.getParameter("month");
String dayParam = req.getParameter("day");
String startParam = req.getParameter("start");
String endParam = req.getParameter("end");
String periodParam = req.getParameter("period");
int requestedYear;
int requestedMonth;
int requestedDay;
try {
if (yearParam != null && monthParam != null) {
// Use year, month parameters if available
requestedYear = Integer.parseInt(yearParam);
requestedMonth = Integer.parseInt(monthParam);
Calendar cal = Calendar.getInstance();
if (dayParam != null) {
requestedDay = Integer.parseInt(dayParam);
cal.set(requestedYear, requestedMonth - 1, requestedDay, 0, 0, 0);
startDate = cal.getTime();
cal.add(Calendar.DATE, 1);
endDate = cal.getTime();
}
else {
cal.set(requestedYear, requestedMonth - 1, 1, 0, 0, 0);
startDate = cal.getTime();
cal.add(Calendar.MONTH, 1);
endDate = cal.getTime();
}
}
else if (startParam != null && endParam != null) {
// Use start, end parameters if available
DateFormat df = new SimpleDateFormat("yyyyMMdd");
startDate = df.parse(startParam);
endDate = df.parse(endParam);
}
else {
if (periodParam == null) {
// Match URL /accesslogs/yearmonth(day) (eg. 201204, 20120401)
String uri = req.getRequestURI();
periodParam = uri.substring(uri.lastIndexOf('/') + 1);
}
Calendar cal = Calendar.getInstance();
if (periodParam.length() == 8) {
DateFormat df = new SimpleDateFormat("yyyyMMdd");
startDate = df.parse(periodParam);
cal.setTime(startDate);
cal.add(Calendar.DATE, 1);
endDate = cal.getTime();
}
else if (periodParam.length() == 6) {
DateFormat df = new SimpleDateFormat("yyyyMM");
startDate = df.parse(periodParam);
cal.setTime(startDate);
cal.add(Calendar.MONTH, 1);
endDate = cal.getTime();
}
else {
throw new Exception("AccessLogProvider: invalid period specified: " + periodParam);
}
}
}
catch (Exception e) {
log.error(e.toString());
return null;
}
return new AccessLogRequest(startDate, endDate);
}
private File[] getRequestedFiles(IVHost vhost, AccessLogRequest request) {
List<File> files = new ArrayList<File>();
String rootPath = vhost.getProperties().getProperty("rootLogPath").toString();
rootPath = rootPath.replace('/', File.separatorChar);
File dir = new File(rootPath);
if (!dir.isDirectory()) {
log.error("AccessLogProvider: rootLogPath is not a directory: " + rootPath);
return files.toArray(new File[files.size()]);
}
Pattern pattern = Pattern.compile(".*access\\.log\\.(\\d{4})-(\\d{2})-(\\d{2})");
for (File file : dir.listFiles()) {
if (file.getName() == "." || file.getName() == "..") {
continue;
}
Matcher m = pattern.matcher(file.getName());
if (m.matches()) {
int year = Integer.parseInt(m.group(1));
int month = Integer.parseInt(m.group(2));
int day = Integer.parseInt(m.group(3));
Date fileDate = MakeDate(year, month, day);
if (DateBetween(fileDate, request.startDate, request.endDate)) {
files.add(file);
}
}
}
return files.toArray(new File[files.size()]);
}
public boolean DateBetween(Date date, Date start, Date end) {
return (date.after(start) && date.before(end));
}
public Date MakeDate(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(year, month - 1, day, 0, 0, 0);
return cal.getTime();
}
public void onHTTPRequest(IVHost vhost, IHTTPRequest httpRequest, IHTTPResponse resp)
{
if (!doHTTPAuthentication(vhost, httpRequest, resp)) {
return;
}
String encodingHeader = httpRequest.getHeader("Accept-Encoding");
boolean gzip = (encodingHeader != null) && encodingHeader.contains("gzip");
OutputStream out;
GZIPOutputStream gzipOut = null;
try {
if (gzip) {
out = gzipOut = new GZIPOutputStream(resp.getOutputStream(), 4096);
}
else {
out = new BufferedOutputStream(resp.getOutputStream());
}
} catch (IOException e) {
log.error("AccessLogProvider: Exception: " + e.toString());
resp.setResponseCode(500);
return;
}
try {
AccessLogRequest request = parseRequestParameters(httpRequest);
if (request != null) {
resp.setResponseCode(200);
resp.setHeader("Content-Type", "text/plain");
if (gzip) {
resp.setHeader("Content-Encoding", "gzip");
}
File[] files = getRequestedFiles(vhost, request);
byte[] buffer = new byte[4096];
DateFormat df = new SimpleDateFormat("yyyyMMdd");
log.info("AccessLogProvider: start=" + df.format(request.startDate) + ", end=" + df.format(request.endDate) + " files=" + files.length + (gzip ? " (gzip)" : ""));
for (File file : files) {
log.info("AccessLogProvider: sending " + file.getName());
InputStream input = new BufferedInputStream(new FileInputStream(file.getAbsolutePath()));
int bytesRead = 0;
int totalBytesRead = 0;
while((bytesRead = input.read(buffer)) > 0){
totalBytesRead += bytesRead;
log.info(String.format("AccessLogProvider: %1$d bytes read", totalBytesRead));
try {
out.write(buffer, 0, bytesRead);
out.flush();
log.info(String.format("AccessLogProvider: %1$d bytes written", totalBytesRead));
}
catch (IOException e) {
log.error("AccessLogProvider: write failed: " + e.toString());
break;
}
}
input.close();
}
out.flush();
if (gzip) {
gzipOut.flush();
gzipOut.finish();
gzipOut.close();
}
out.close();
}
else {
log.error("AccessLogProvider: invalid URI: " + httpRequest.getRequestURI());
resp.setResponseCode(404);
}
}
catch (Exception e) {
log.error("AccessLogProvider: Exception: " + e.toString());
resp.setResponseCode(500);
}
}
}