Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

CAPEDWARF-14 Log to data grid

CAPEDWARF-27 Logging should also log information about the request
  • Loading branch information...
commit 5dd5875f494d43e1acc3f907947b169c00da1382 1 parent 802be9e
Marko Lukša luksa authored
Showing with 757 additions and 3 deletions.
  1. +5 −0 admin/pom.xml
  2. +3 −0  admin/src/main/java/org/jboss/capedwarf/admin/AdminExtension.java
  3. +81 −0 admin/src/main/java/org/jboss/capedwarf/admin/LogViewer.java
  4. +37 −0 admin/src/main/java/org/jboss/capedwarf/admin/SizeFormatter.java
  5. +37 −0 admin/src/main/java/org/jboss/capedwarf/admin/TimeFormatter.java
  6. +33 −1 admin/src/main/resources/org/jboss/capedwarf/admin/header.vm
  7. +54 −0 admin/src/main/resources/org/jboss/capedwarf/admin/logs.vm
  8. +5 −0 appidentity/pom.xml
  9. +11 −0 appidentity/src/main/java/org/jboss/capedwarf/appidentity/GAEListener.java
  10. +1 −0  bytecode/src/main/java/org/jboss/capedwarf/bytecode/FactoriesTransformer.java
  11. +36 −0 bytecode/src/main/java/org/jboss/capedwarf/bytecode/LogServiceFactoryTransformer.java
  12. +83 −0 log/pom.xml
  13. +229 −0 log/src/main/java/org/jboss/capedwarf/log/CapedwarfLogService.java
  14. +5 −2 .../main/java/org/jboss/capedwarf/common/logging → log/src/main/java/org/jboss/capedwarf/log}/Logger.java
  15. +73 −0 log/src/test/java/org/jboss/test/capedwarf/log/LoggingTest.java
  16. +27 −0 log/src/test/resources/appengine-web.xml
  17. +30 −0 log/src/test/resources/arquillian.xml
  18. +7 −0 pom.xml
5 admin/pom.xml
View
@@ -49,6 +49,11 @@
</dependency>
<dependency>
+ <groupId>org.jboss.capedwarf.blue</groupId>
+ <artifactId>capedwarf-log</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</dependency>
3  admin/src/main/java/org/jboss/capedwarf/admin/AdminExtension.java
View
@@ -23,6 +23,9 @@ public void register(@Observes BeforeBeanDiscovery bbd, BeanManager bm) {
addAnnotatedType(bbd, bm, DatastoreEntityViewer.class);
addAnnotatedType(bbd, bm, DatastoreViewer.class);
addAnnotatedType(bbd, bm, HttpParamProducer.class);
+ addAnnotatedType(bbd, bm, LogViewer.class);
+ addAnnotatedType(bbd, bm, TimeFormatter.class);
+ addAnnotatedType(bbd, bm, SizeFormatter.class);
}
private <E> void addAnnotatedType(BeforeBeanDiscovery bbd, BeanManager bm, Class<E> clazz) {
81 admin/src/main/java/org/jboss/capedwarf/admin/LogViewer.java
View
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.capedwarf.admin;
+
+import com.google.appengine.api.log.LogQuery;
+import com.google.appengine.api.log.LogService;
+import com.google.appengine.api.log.LogServiceFactory;
+import com.google.appengine.api.log.RequestLogs;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
+ */
+@Named("logViewer")
+@RequestScoped
+public class LogViewer {
+
+ @Inject @HttpParam
+ private String show;
+
+ @Inject @HttpParam
+ private String severity;
+
+ public boolean isShowAll() {
+ return show == null || show.equals("all");
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+ public void setSeverity(String severity) {
+ this.severity = severity;
+ }
+
+ public List<String> getSeverities() {
+ List<String> list = new ArrayList<String>();
+ for (LogService.LogLevel level : LogService.LogLevel.values()) {
+ list.add(level.name());
+ }
+ return list;
+ }
+
+ public Iterable<RequestLogs> getRequestLogs() {
+ LogQuery logQuery = new LogQuery();
+ if (!isShowAll()) {
+ logQuery = logQuery.minLogLevel(LogService.LogLevel.valueOf(severity));
+ }
+ // TODO: add other fields to filter
+ return LogServiceFactory.getLogService().fetch(logQuery);
+ }
+
+}
37 admin/src/main/java/org/jboss/capedwarf/admin/SizeFormatter.java
View
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.capedwarf.admin;
+
+import javax.inject.Named;
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
+ */
+@Named
+public class SizeFormatter {
+
+ public String format(long bytes) {
+ return (bytes / 1000) + "kb";
+ }
+}
37 admin/src/main/java/org/jboss/capedwarf/admin/TimeFormatter.java
View
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.capedwarf.admin;
+
+import javax.inject.Named;
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
+ */
+@Named
+public class TimeFormatter {
+
+ public String format(long millis) {
+ return new Date(millis).toString();
+ }
+}
34 admin/src/main/resources/org/jboss/capedwarf/admin/header.vm
View
@@ -136,6 +136,38 @@
font-weight: bold;
padding-bottom: 10px;
}
+
+ .ae-log-severity {
+ display: block;
+ height: 1.2em;
+ width: 1.2em;
+ line-height: 1.2;
+ text-align: center;
+ text-transform: capitalize;
+ font-weight: bold;
+ border-radius: 2px;
+ }
+
+ .ae-log-severity-D {
+ background-color: #09F;
+ }
+
+ .ae-log-severity-I {
+ background-color: #3C0;
+ }
+
+ .ae-log-severity-W {
+ background-color: #FD0;
+ }
+
+ .ae-log-severity-E {
+ background-color: #F90;
+ }
+
+ .ae-log-severity-F {
+ background-color: #F22;
+ }
+
</style>
</head>
<body>
@@ -158,7 +190,7 @@
<a href="#">Instances</a>
</li>
<li>
- <a href="#">Logs</a>
+ <a href="logs.vm">Logs</a>
</li>
<li>
<a href="#">Versions</a>
54 admin/src/main/resources/org/jboss/capedwarf/admin/logs.vm
View
@@ -0,0 +1,54 @@
+#include("/org/jboss/capedwarf/admin/header.vm")
+
+<h2>Logs</h2>
+<form action="logs.vm">
+ Show:
+ <input type="radio" name="show" value="all" id="showAll" #if($logViewer.showAll) checked="checked" #end />
+ <label for="showAll">All requests</label>
+
+ <input type="radio" name="show" value="withMinimumSeverity" #if(!$logViewer.showAll) checked="checked" #end id="showWithMinimumSeverity"/>
+ <label for="showWithMinimumSeverity">Logs with minimum severity:</label>
+
+ <select id="severitySelect" name="severity">
+ #foreach($severity in $logViewer.severities)
+ <option value="$severity" #if($severity.equals($logViewer.severity)) selected="selected" #end>$severity</option>
+ #end
+ </select>
+ <input type="submit" value="Search"/>
+</form>
+
+<br/><br/>
+
+<table width="100%">
+ #foreach ($requestLog in $logViewer.requestLogs)
+ <tr>
+ <td colspan="3">
+ $timeFormatter.format($requestLog.endTimeUsec)
+ <strong>$requestLog.resource</strong>
+ $requestLog.status
+ ${requestLog.pendingTimeUsec}ms
+ $sizeFormatter.format($requestLog.responseSize)
+ $requestLog.userAgent
+ </td>
+ </tr>
+ #foreach ($appLogLine in $requestLog.appLogLines)
+ <tr>
+ <td><span class="ae-log-severity ae-log-severity-$appLogLine.logLevel.name().charAt(0)">$appLogLine.logLevel.name().charAt(0)</span></td>
+ <td>$timeFormatter.format($appLogLine.timeUsec)</td>
+ <td>$appLogLine.logMessage</td>
+ </tr>
+ #end
+ #end
+</table>
+
+<div class="ae-log-legend">
+ <strong>Legend:</strong>
+ #foreach($severity in $logViewer.severities)
+ <span>
+ <span class="ae-log-severity ae-log-severity-$severity.charAt(0)">$severity.charAt(0)</span>
+ $severity
+ </span>
+ #end
+</div>
+
+#include("/org/jboss/capedwarf/admin/footer.vm")
5 appidentity/pom.xml
View
@@ -27,6 +27,11 @@
</dependency>
<dependency>
+ <groupId>org.jboss.capedwarf.blue</groupId>
+ <artifactId>capedwarf-log</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</dependency>
11 appidentity/src/main/java/org/jboss/capedwarf/appidentity/GAEListener.java
View
@@ -22,6 +22,7 @@
package org.jboss.capedwarf.appidentity;
+import com.google.appengine.api.log.LogServiceFactory;
import org.jboss.capedwarf.common.config.AppEngineWebXml;
import org.jboss.capedwarf.common.config.AppEngineWebXmlParser;
import org.jboss.capedwarf.common.config.CapedwarfConfiguration;
@@ -29,6 +30,7 @@
import org.jboss.capedwarf.common.config.JBossEnvironment;
import org.jboss.capedwarf.common.infinispan.InfinispanUtils;
import org.jboss.capedwarf.common.io.IOUtils;
+import org.jboss.capedwarf.log.CapedwarfLogService;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
@@ -81,15 +83,24 @@ public void contextDestroyed(ServletContextEvent sce) {
}
public void requestInitialized(ServletRequestEvent sre) {
+ long requestStartMillis = System.currentTimeMillis();
+
final ServletRequest req = sre.getServletRequest();
if (req instanceof HttpServletRequest)
initJBossEnvironment((HttpServletRequest) req);
+
+ getLogService().requestStarted(sre.getServletRequest(), requestStartMillis);
}
public void requestDestroyed(ServletRequestEvent sre) {
+ getLogService().requestFinished(sre.getServletRequest());
clearJBossEnvironment();
}
+ private CapedwarfLogService getLogService() {
+ return ((CapedwarfLogService) LogServiceFactory.getLogService());
+ }
+
private AppEngineWebXml readAppEngineWebXml() throws IOException {
InputStream stream = getWebResourceAsStream(APPENGINE_WEB_XML);
if (stream == null)
1  bytecode/src/main/java/org/jboss/capedwarf/bytecode/FactoriesTransformer.java
View
@@ -39,6 +39,7 @@ public FactoriesTransformer() {
register("com.google.appengine.api.datastore.Key", new KeyTransformer());
register("com.google.appengine.api.files.FileServiceFactory", new FileServiceFactoryTransformer());
register("com.google.appengine.api.images.ImagesServiceFactory", new ImagesServiceFactoryTransformer());
+ register("com.google.appengine.api.log.LogServiceFactory", new LogServiceFactoryTransformer());
register("com.google.appengine.api.mail.MailServiceFactory", new MailServiceFactoryTransformer());
register("com.google.appengine.api.memcache.MemcacheServiceFactory", new MemcacheServiceFactoryTransformer());
register("com.google.appengine.api.urlfetch.URLFetchServiceFactory", new URLFetchServiceFactoryTransformer());
36 bytecode/src/main/java/org/jboss/capedwarf/bytecode/LogServiceFactoryTransformer.java
View
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.capedwarf.bytecode;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+
+/**
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
+ */
+public class LogServiceFactoryTransformer extends JavassistTransformer {
+ protected void transform(CtClass clazz) throws Exception {
+ CtMethod method = clazz.getDeclaredMethod("getLogService");
+ method.setBody("return new org.jboss.capedwarf.log.CapedwarfLogService();");
+ }
+}
83 log/pom.xml
View
@@ -0,0 +1,83 @@
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2012, Red Hat, Inc., and individual contributors
+ ~ as indicated by the @author tags. See the copyright.txt file in the
+ ~ distribution for a full listing of individual contributors.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!-- Parent -->
+ <parent>
+ <groupId>org.jboss.capedwarf.blue</groupId>
+ <artifactId>capedwarf-build</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>capedwarf-log</artifactId>
+ <packaging>jar</packaging>
+ <name>CapeDwarf Log</name>
+ <url>http://www.jboss.org/capedwarf</url>
+ <description>CapeDwarf Log</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.jboss.capedwarf.blue</groupId>
+ <artifactId>capedwarf-common</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.appengine</groupId>
+ <artifactId>appengine-api-1.0-sdk</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.spec.javax.servlet</groupId>
+ <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-arquillian-container-remote</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.arquillian.protocol</groupId>
+ <artifactId>arquillian-protocol-servlet</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
229 log/src/main/java/org/jboss/capedwarf/log/CapedwarfLogService.java
View
@@ -0,0 +1,229 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.capedwarf.log;
+
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.FetchOptions;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.Query;
+import com.google.appengine.api.log.AppLogLine;
+import com.google.appengine.api.log.LogQuery;
+import com.google.appengine.api.log.LogService;
+import com.google.appengine.api.log.RequestLogs;
+import com.google.apphosting.api.ApiProxy;
+import org.jboss.capedwarf.common.apiproxy.JBossDelegate;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+/**
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
+ */
+public class CapedwarfLogService implements LogService {
+
+ private static final String LOG_REQUEST_ENTITY_KIND = "__org.jboss.capedwarf.LogRequest__";
+ private static final String LOG_REQUEST_START_TIME_MILLIS = "startTimeMillis";
+ private static final String LOG_REQUEST_END_TIME_MILLIS = "endTimeMillis";
+ private static final String LOG_REQUEST_URI = "uri";
+ private static final String LOG_REQUEST_USER_AGENT = "userAgent";
+
+ private static final String LOG_LINE_ENTITY_KIND = "__org.jboss.capedwarf.LogLine__";
+ private static final String LOG_LINE_REQUEST_KEY = "requestKey";
+ private static final String LOG_LINE_MILLIS = "millis";
+ private static final String LOG_LINE_LEVEL = "level";
+ private static final String LOG_LINE_MESSAGE = "message";
+ private static final String LOG_LINE_LOGGER = "logger";
+ private static final String LOG_LINE_THROWN = "thrown";
+
+ private static final String LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE = "__org.jboss.capedwarf.LogRequest__";
+
+
+ public Iterable<RequestLogs> fetch(LogQuery logQuery) {
+ List<RequestLogs> list = new ArrayList<RequestLogs>();
+
+ Map<Key, RequestLogs> map = fetchRequestLogs(logQuery, list);
+ fetchAppLogLines(logQuery, map);
+ if (logQuery.getMinLogLevel() != null) {
+ removeRequestsWithNoLogLines(list);
+ }
+ return list;
+ }
+
+ private void removeRequestsWithNoLogLines(List<RequestLogs> list) {
+ for (Iterator<RequestLogs> iterator = list.iterator(); iterator.hasNext(); ) {
+ RequestLogs requestLogs = iterator.next();
+ if (requestLogs.getAppLogLines().isEmpty()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ private Map<Key, RequestLogs> fetchRequestLogs(LogQuery logQuery, List<RequestLogs> list) {
+ Map<Key, RequestLogs> map = new HashMap<Key, RequestLogs>();
+
+ Query query = createRequestLogsQuery(logQuery);
+ FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
+
+ List<Entity> entities = DatastoreServiceFactory.getDatastoreService().prepare(query).asList(fetchOptions);
+ for (Entity entity : entities) {
+ RequestLogs requestLogs = new RequestLogs();
+ Long startTimeUsec = (Long) entity.getProperty(LOG_REQUEST_START_TIME_MILLIS);
+ if (startTimeUsec != null) {
+ requestLogs.setStartTimeUsec(startTimeUsec);
+ }
+ Long endTimeUsec = (Long) entity.getProperty(LOG_REQUEST_END_TIME_MILLIS);
+ if (endTimeUsec == null) {
+ requestLogs.setFinished(false);
+ } else {
+ requestLogs.setEndTimeUsec(endTimeUsec);
+ requestLogs.setPendingTime(requestLogs.getEndTimeUsec() - requestLogs.getStartTimeUsec());
+ }
+ requestLogs.setResource((String) entity.getProperty(LOG_REQUEST_URI));
+ requestLogs.setUserAgent((String) entity.getProperty(LOG_REQUEST_USER_AGENT));
+ // TODO: set all other properties
+
+ map.put(entity.getKey(), requestLogs);
+ list.add(requestLogs);
+ }
+ return map;
+ }
+
+ private Query createRequestLogsQuery(LogQuery logQuery) {
+ Query query = new Query(LOG_REQUEST_ENTITY_KIND);
+ if (logQuery.getStartTimeUsec() != null) {
+ query.addFilter(LOG_REQUEST_END_TIME_MILLIS, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getStartTimeUsec());
+ }
+ if (logQuery.getEndTimeUsec() != null) {
+ query.addFilter(LOG_REQUEST_END_TIME_MILLIS, Query.FilterOperator.LESS_THAN_OR_EQUAL, logQuery.getEndTimeUsec());
+ }
+ query.addSort(LOG_REQUEST_END_TIME_MILLIS);
+ return query;
+ }
+
+ private void fetchAppLogLines(LogQuery logQuery, Map<Key, RequestLogs> map) {
+ Query query = createAppLogLinesQuery(logQuery);
+ FetchOptions fetchOptions = createAppLogFetchOptions(logQuery);
+
+ List<Entity> entities = DatastoreServiceFactory.getDatastoreService().prepare(query).asList(fetchOptions);
+ for (Entity entity : entities) {
+ AppLogLine logLine = new AppLogLine();
+ logLine.setLogLevel(LogLevel.values()[(Integer) entity.getProperty(LOG_LINE_LEVEL)]);
+ logLine.setLogMessage((String) entity.getProperty(LOG_LINE_MESSAGE));
+ logLine.setTimeUsec((Long) entity.getProperty(LOG_LINE_MILLIS));
+
+ RequestLogs requestLogs = map.get((Key) entity.getProperty(LOG_LINE_REQUEST_KEY));
+ requestLogs.getAppLogLines().add(logLine);
+ }
+ }
+
+ private Query createAppLogLinesQuery(LogQuery logQuery) {
+ Query query = new Query(LOG_LINE_ENTITY_KIND);
+ if (logQuery.getMinLogLevel() != null) {
+ query.addFilter(LOG_LINE_LEVEL, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getMinLogLevel().ordinal());
+ }
+ if (logQuery.getStartTimeUsec() != null) {
+ query.addFilter(LOG_LINE_MILLIS, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getStartTimeUsec());
+ }
+ if (logQuery.getEndTimeUsec() != null) {
+ query.addFilter(LOG_LINE_MILLIS, Query.FilterOperator.LESS_THAN_OR_EQUAL, logQuery.getEndTimeUsec());
+ }
+ query.addSort(LOG_LINE_MILLIS);
+ return query;
+ }
+
+ private FetchOptions createAppLogFetchOptions(LogQuery logQuery) {
+ FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
+ if (logQuery.getBatchSize() != null) {
+ fetchOptions = fetchOptions.limit(logQuery.getBatchSize());
+ }
+ return fetchOptions;
+ }
+
+ public void log(LogRecord record) {
+ JBossDelegate jBossDelegate = (JBossDelegate) ApiProxy.getDelegate();
+ ServletRequest request = jBossDelegate.getServletRequest();
+
+ Entity entity = new Entity(LOG_LINE_ENTITY_KIND);
+ entity.setProperty(LOG_LINE_LOGGER, record.getLoggerName());
+ entity.setProperty(LOG_LINE_LEVEL, getLogLevel(record).ordinal());
+ entity.setProperty(LOG_LINE_MILLIS, record.getMillis());
+ entity.setProperty(LOG_LINE_THROWN, record.getThrown());
+ entity.setProperty(LOG_LINE_MESSAGE, record.getMessage()); // TODO: format message
+ entity.setProperty(LOG_LINE_REQUEST_KEY, getRequestEntityKey(request));
+ DatastoreServiceFactory.getAsyncDatastoreService().put(entity);
+ }
+
+ private LogLevel getLogLevel(LogRecord record) {
+ // TODO
+ if (record.getLevel().equals(Level.INFO)) {
+ return LogLevel.INFO;
+ } else if (record.getLevel().equals(Level.WARNING)) {
+ return LogLevel.WARN;
+ } else if (record.getLevel().equals(Level.SEVERE)) {
+ return LogLevel.ERROR;
+ } else if (record.getLevel().equals(Level.FINE)) {
+ return LogLevel.DEBUG;
+ } else {
+ return LogLevel.INFO;
+ }
+ }
+
+ public void requestStarted(ServletRequest servletRequest, long startTimeMillis) {
+ Entity entity = new Entity(LOG_REQUEST_ENTITY_KIND);
+ entity.setProperty(LOG_REQUEST_START_TIME_MILLIS, startTimeMillis);
+
+ if (servletRequest instanceof HttpServletRequest) {
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ entity.setProperty(LOG_REQUEST_URI, request.getRequestURI());
+ entity.setProperty(LOG_REQUEST_USER_AGENT, request.getHeader("User-Agent"));
+ }
+
+ DatastoreServiceFactory.getDatastoreService().put(entity);
+ servletRequest.setAttribute(LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE, entity);
+ }
+
+ public void requestFinished(ServletRequest servletRequest) {
+ Entity entity = getRequestEntity(servletRequest);
+ entity.setProperty(LOG_REQUEST_END_TIME_MILLIS, System.currentTimeMillis());
+
+// HttpServletResponse response;
+ // TODO entity.setProperty("responseStatusCode", response.getStatus());
+ // TODO entity.setProperty("responseLength", );
+ }
+
+ private Entity getRequestEntity(ServletRequest request) {
+ return (Entity) request.getAttribute(LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE);
+ }
+
+ private Key getRequestEntityKey(ServletRequest request) {
+ return getRequestEntity(request).getKey();
+ }
+}
7 ...va/org/jboss/capedwarf/common/logging/Logger.java → ...src/main/java/org/jboss/capedwarf/log/Logger.java
View
@@ -20,7 +20,9 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.jboss.capedwarf.common.logging;
+package org.jboss.capedwarf.log;
+
+import com.google.appengine.api.log.LogServiceFactory;
import java.util.logging.LogRecord;
@@ -28,10 +30,11 @@
* Logger.
*
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
+ * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
*/
public class Logger {
public static void publish(LogRecord record) {
- // TODO
+ ((CapedwarfLogService)LogServiceFactory.getLogService()).log(record);
}
public static void flush() {
73 log/src/test/java/org/jboss/test/capedwarf/log/LoggingTest.java
View
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.capedwarf.log;
+
+import com.google.appengine.api.log.AppLogLine;
+import com.google.appengine.api.log.LogQuery;
+import com.google.appengine.api.log.LogServiceFactory;
+import com.google.appengine.api.log.RequestLogs;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+@RunWith(Arquillian.class)
+public class LoggingTest {
+
+ @Deployment
+ public static Archive getDeployment() {
+ return ShrinkWrap.create(WebArchive.class)
+ .setWebXML(new StringAsset("<web/>"))
+ .addAsWebInfResource("appengine-web.xml");
+ }
+
+ @Test
+ public void testLogging() {
+ Logger log = Logger.getLogger("TestLogger");
+ log.info("hello");
+
+ Iterable<RequestLogs> iterable = LogServiceFactory.getLogService().fetch(new LogQuery());
+ Assert.assertTrue(iterable.iterator().hasNext());
+
+ for (RequestLogs requestLogs : iterable) {
+ List<AppLogLine> appLogLines = requestLogs.getAppLogLines();
+ for (AppLogLine appLogLine : appLogLines) {
+ if ("hello".equals(appLogLine.getLogMessage())) {
+ return; // test passes
+ }
+ }
+ }
+ Assert.fail("Did not find 'hello' in logs.");
+ }
+}
27 log/src/test/resources/appengine-web.xml
View
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2012, Red Hat, Inc., and individual contributors
+ ~ as indicated by the @author tags. See the copyright.txt file in the
+ ~ distribution for a full listing of individual contributors.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ -->
+
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+ <application>test</application>
+ <version>1</version>
+</appengine-web-app>
30 log/src/test/resources/arquillian.xml
View
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2012, Red Hat, Inc., and individual contributors
+ ~ as indicated by the @author tags. See the copyright.txt file in the
+ ~ distribution for a full listing of individual contributors.
+ ~
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
+ ~
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ -->
+
+<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://jboss.org/schema/arquillian"
+ xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+ <defaultProtocol type="Servlet 3.0"/>
+
+</arquillian>
7 pom.xml
View
@@ -29,6 +29,7 @@
<module>environment</module>
<module>files</module>
<module>images</module>
+ <module>log</module>
<module>mail</module>
<module>memcache</module>
<module>multitenancy</module>
@@ -282,6 +283,12 @@
<dependency>
<groupId>org.jboss.capedwarf.blue</groupId>
+ <artifactId>capedwarf-log</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.capedwarf.blue</groupId>
<artifactId>capedwarf-mail</artifactId>
<version>${project.version}</version>
</dependency>
Please sign in to comment.
Something went wrong with that request. Please try again.