Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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 18 changed files with 757 additions and 3 deletions. Show diff stats Hide diff stats

  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
@@ -49,6 +49,11 @@
49 49 </dependency>
50 50
51 51 <dependency>
  52 + <groupId>org.jboss.capedwarf.blue</groupId>
  53 + <artifactId>capedwarf-log</artifactId>
  54 + </dependency>
  55 +
  56 + <dependency>
52 57 <groupId>javax.enterprise</groupId>
53 58 <artifactId>cdi-api</artifactId>
54 59 </dependency>
3  admin/src/main/java/org/jboss/capedwarf/admin/AdminExtension.java
@@ -23,6 +23,9 @@ public void register(@Observes BeforeBeanDiscovery bbd, BeanManager bm) {
23 23 addAnnotatedType(bbd, bm, DatastoreEntityViewer.class);
24 24 addAnnotatedType(bbd, bm, DatastoreViewer.class);
25 25 addAnnotatedType(bbd, bm, HttpParamProducer.class);
  26 + addAnnotatedType(bbd, bm, LogViewer.class);
  27 + addAnnotatedType(bbd, bm, TimeFormatter.class);
  28 + addAnnotatedType(bbd, bm, SizeFormatter.class);
26 29 }
27 30
28 31 private <E> void addAnnotatedType(BeforeBeanDiscovery bbd, BeanManager bm, Class<E> clazz) {
81 admin/src/main/java/org/jboss/capedwarf/admin/LogViewer.java
... ... @@ -0,0 +1,81 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.capedwarf.admin;
  24 +
  25 +import com.google.appengine.api.log.LogQuery;
  26 +import com.google.appengine.api.log.LogService;
  27 +import com.google.appengine.api.log.LogServiceFactory;
  28 +import com.google.appengine.api.log.RequestLogs;
  29 +
  30 +import javax.enterprise.context.RequestScoped;
  31 +import javax.inject.Inject;
  32 +import javax.inject.Named;
  33 +import java.util.ArrayList;
  34 +import java.util.List;
  35 +import java.util.Set;
  36 +import java.util.SortedSet;
  37 +import java.util.TreeSet;
  38 +
  39 +/**
  40 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
  41 + */
  42 +@Named("logViewer")
  43 +@RequestScoped
  44 +public class LogViewer {
  45 +
  46 + @Inject @HttpParam
  47 + private String show;
  48 +
  49 + @Inject @HttpParam
  50 + private String severity;
  51 +
  52 + public boolean isShowAll() {
  53 + return show == null || show.equals("all");
  54 + }
  55 +
  56 + public String getSeverity() {
  57 + return severity;
  58 + }
  59 +
  60 + public void setSeverity(String severity) {
  61 + this.severity = severity;
  62 + }
  63 +
  64 + public List<String> getSeverities() {
  65 + List<String> list = new ArrayList<String>();
  66 + for (LogService.LogLevel level : LogService.LogLevel.values()) {
  67 + list.add(level.name());
  68 + }
  69 + return list;
  70 + }
  71 +
  72 + public Iterable<RequestLogs> getRequestLogs() {
  73 + LogQuery logQuery = new LogQuery();
  74 + if (!isShowAll()) {
  75 + logQuery = logQuery.minLogLevel(LogService.LogLevel.valueOf(severity));
  76 + }
  77 + // TODO: add other fields to filter
  78 + return LogServiceFactory.getLogService().fetch(logQuery);
  79 + }
  80 +
  81 +}
37 admin/src/main/java/org/jboss/capedwarf/admin/SizeFormatter.java
... ... @@ -0,0 +1,37 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.capedwarf.admin;
  24 +
  25 +import javax.inject.Named;
  26 +import java.util.Date;
  27 +
  28 +/**
  29 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
  30 + */
  31 +@Named
  32 +public class SizeFormatter {
  33 +
  34 + public String format(long bytes) {
  35 + return (bytes / 1000) + "kb";
  36 + }
  37 +}
37 admin/src/main/java/org/jboss/capedwarf/admin/TimeFormatter.java
... ... @@ -0,0 +1,37 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.capedwarf.admin;
  24 +
  25 +import javax.inject.Named;
  26 +import java.util.Date;
  27 +
  28 +/**
  29 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
  30 + */
  31 +@Named
  32 +public class TimeFormatter {
  33 +
  34 + public String format(long millis) {
  35 + return new Date(millis).toString();
  36 + }
  37 +}
34 admin/src/main/resources/org/jboss/capedwarf/admin/header.vm
@@ -136,6 +136,38 @@
136 136 font-weight: bold;
137 137 padding-bottom: 10px;
138 138 }
  139 +
  140 + .ae-log-severity {
  141 + display: block;
  142 + height: 1.2em;
  143 + width: 1.2em;
  144 + line-height: 1.2;
  145 + text-align: center;
  146 + text-transform: capitalize;
  147 + font-weight: bold;
  148 + border-radius: 2px;
  149 + }
  150 +
  151 + .ae-log-severity-D {
  152 + background-color: #09F;
  153 + }
  154 +
  155 + .ae-log-severity-I {
  156 + background-color: #3C0;
  157 + }
  158 +
  159 + .ae-log-severity-W {
  160 + background-color: #FD0;
  161 + }
  162 +
  163 + .ae-log-severity-E {
  164 + background-color: #F90;
  165 + }
  166 +
  167 + .ae-log-severity-F {
  168 + background-color: #F22;
  169 + }
  170 +
139 171 </style>
140 172 </head>
141 173 <body>
@@ -158,7 +190,7 @@
158 190 <a href="#">Instances</a>
159 191 </li>
160 192 <li>
161   - <a href="#">Logs</a>
  193 + <a href="logs.vm">Logs</a>
162 194 </li>
163 195 <li>
164 196 <a href="#">Versions</a>
54 admin/src/main/resources/org/jboss/capedwarf/admin/logs.vm
... ... @@ -0,0 +1,54 @@
  1 +#include("/org/jboss/capedwarf/admin/header.vm")
  2 +
  3 +<h2>Logs</h2>
  4 +<form action="logs.vm">
  5 + Show:
  6 + <input type="radio" name="show" value="all" id="showAll" #if($logViewer.showAll) checked="checked" #end />
  7 + <label for="showAll">All requests</label>
  8 +
  9 + <input type="radio" name="show" value="withMinimumSeverity" #if(!$logViewer.showAll) checked="checked" #end id="showWithMinimumSeverity"/>
  10 + <label for="showWithMinimumSeverity">Logs with minimum severity:</label>
  11 +
  12 + <select id="severitySelect" name="severity">
  13 + #foreach($severity in $logViewer.severities)
  14 + <option value="$severity" #if($severity.equals($logViewer.severity)) selected="selected" #end>$severity</option>
  15 + #end
  16 + </select>
  17 + <input type="submit" value="Search"/>
  18 +</form>
  19 +
  20 +<br/><br/>
  21 +
  22 +<table width="100%">
  23 + #foreach ($requestLog in $logViewer.requestLogs)
  24 + <tr>
  25 + <td colspan="3">
  26 + $timeFormatter.format($requestLog.endTimeUsec)
  27 + <strong>$requestLog.resource</strong>
  28 + $requestLog.status
  29 + ${requestLog.pendingTimeUsec}ms
  30 + $sizeFormatter.format($requestLog.responseSize)
  31 + $requestLog.userAgent
  32 + </td>
  33 + </tr>
  34 + #foreach ($appLogLine in $requestLog.appLogLines)
  35 + <tr>
  36 + <td><span class="ae-log-severity ae-log-severity-$appLogLine.logLevel.name().charAt(0)">$appLogLine.logLevel.name().charAt(0)</span></td>
  37 + <td>$timeFormatter.format($appLogLine.timeUsec)</td>
  38 + <td>$appLogLine.logMessage</td>
  39 + </tr>
  40 + #end
  41 + #end
  42 +</table>
  43 +
  44 +<div class="ae-log-legend">
  45 + <strong>Legend:</strong>
  46 + #foreach($severity in $logViewer.severities)
  47 + <span>
  48 + <span class="ae-log-severity ae-log-severity-$severity.charAt(0)">$severity.charAt(0)</span>
  49 + $severity
  50 + </span>
  51 + #end
  52 +</div>
  53 +
  54 +#include("/org/jboss/capedwarf/admin/footer.vm")
5 appidentity/pom.xml
@@ -27,6 +27,11 @@
27 27 </dependency>
28 28
29 29 <dependency>
  30 + <groupId>org.jboss.capedwarf.blue</groupId>
  31 + <artifactId>capedwarf-log</artifactId>
  32 + </dependency>
  33 +
  34 + <dependency>
30 35 <groupId>javax.enterprise</groupId>
31 36 <artifactId>cdi-api</artifactId>
32 37 </dependency>
11 appidentity/src/main/java/org/jboss/capedwarf/appidentity/GAEListener.java
@@ -22,6 +22,7 @@
22 22
23 23 package org.jboss.capedwarf.appidentity;
24 24
  25 +import com.google.appengine.api.log.LogServiceFactory;
25 26 import org.jboss.capedwarf.common.config.AppEngineWebXml;
26 27 import org.jboss.capedwarf.common.config.AppEngineWebXmlParser;
27 28 import org.jboss.capedwarf.common.config.CapedwarfConfiguration;
@@ -29,6 +30,7 @@
29 30 import org.jboss.capedwarf.common.config.JBossEnvironment;
30 31 import org.jboss.capedwarf.common.infinispan.InfinispanUtils;
31 32 import org.jboss.capedwarf.common.io.IOUtils;
  33 +import org.jboss.capedwarf.log.CapedwarfLogService;
32 34
33 35 import javax.servlet.ServletContext;
34 36 import javax.servlet.ServletContextEvent;
@@ -81,15 +83,24 @@ public void contextDestroyed(ServletContextEvent sce) {
81 83 }
82 84
83 85 public void requestInitialized(ServletRequestEvent sre) {
  86 + long requestStartMillis = System.currentTimeMillis();
  87 +
84 88 final ServletRequest req = sre.getServletRequest();
85 89 if (req instanceof HttpServletRequest)
86 90 initJBossEnvironment((HttpServletRequest) req);
  91 +
  92 + getLogService().requestStarted(sre.getServletRequest(), requestStartMillis);
87 93 }
88 94
89 95 public void requestDestroyed(ServletRequestEvent sre) {
  96 + getLogService().requestFinished(sre.getServletRequest());
90 97 clearJBossEnvironment();
91 98 }
92 99
  100 + private CapedwarfLogService getLogService() {
  101 + return ((CapedwarfLogService) LogServiceFactory.getLogService());
  102 + }
  103 +
93 104 private AppEngineWebXml readAppEngineWebXml() throws IOException {
94 105 InputStream stream = getWebResourceAsStream(APPENGINE_WEB_XML);
95 106 if (stream == null)
1  bytecode/src/main/java/org/jboss/capedwarf/bytecode/FactoriesTransformer.java
@@ -39,6 +39,7 @@ public FactoriesTransformer() {
39 39 register("com.google.appengine.api.datastore.Key", new KeyTransformer());
40 40 register("com.google.appengine.api.files.FileServiceFactory", new FileServiceFactoryTransformer());
41 41 register("com.google.appengine.api.images.ImagesServiceFactory", new ImagesServiceFactoryTransformer());
  42 + register("com.google.appengine.api.log.LogServiceFactory", new LogServiceFactoryTransformer());
42 43 register("com.google.appengine.api.mail.MailServiceFactory", new MailServiceFactoryTransformer());
43 44 register("com.google.appengine.api.memcache.MemcacheServiceFactory", new MemcacheServiceFactoryTransformer());
44 45 register("com.google.appengine.api.urlfetch.URLFetchServiceFactory", new URLFetchServiceFactoryTransformer());
36 bytecode/src/main/java/org/jboss/capedwarf/bytecode/LogServiceFactoryTransformer.java
... ... @@ -0,0 +1,36 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.capedwarf.bytecode;
  24 +
  25 +import javassist.CtClass;
  26 +import javassist.CtMethod;
  27 +
  28 +/**
  29 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
  30 + */
  31 +public class LogServiceFactoryTransformer extends JavassistTransformer {
  32 + protected void transform(CtClass clazz) throws Exception {
  33 + CtMethod method = clazz.getDeclaredMethod("getLogService");
  34 + method.setBody("return new org.jboss.capedwarf.log.CapedwarfLogService();");
  35 + }
  36 +}
83 log/pom.xml
... ... @@ -0,0 +1,83 @@
  1 +<!--
  2 + ~ JBoss, Home of Professional Open Source.
  3 + ~ Copyright 2012, Red Hat, Inc., and individual contributors
  4 + ~ as indicated by the @author tags. See the copyright.txt file in the
  5 + ~ distribution for a full listing of individual contributors.
  6 + ~
  7 + ~ This is free software; you can redistribute it and/or modify it
  8 + ~ under the terms of the GNU Lesser General Public License as
  9 + ~ published by the Free Software Foundation; either version 2.1 of
  10 + ~ the License, or (at your option) any later version.
  11 + ~
  12 + ~ This software is distributed in the hope that it will be useful,
  13 + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + ~ Lesser General Public License for more details.
  16 + ~
  17 + ~ You should have received a copy of the GNU Lesser General Public
  18 + ~ License along with this software; if not, write to the Free
  19 + ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + -->
  22 +
  23 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  24 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  25 + <!-- Parent -->
  26 + <parent>
  27 + <groupId>org.jboss.capedwarf.blue</groupId>
  28 + <artifactId>capedwarf-build</artifactId>
  29 + <version>1.0.0-SNAPSHOT</version>
  30 + </parent>
  31 +
  32 + <modelVersion>4.0.0</modelVersion>
  33 + <artifactId>capedwarf-log</artifactId>
  34 + <packaging>jar</packaging>
  35 + <name>CapeDwarf Log</name>
  36 + <url>http://www.jboss.org/capedwarf</url>
  37 + <description>CapeDwarf Log</description>
  38 +
  39 + <dependencies>
  40 +
  41 + <dependency>
  42 + <groupId>org.jboss.capedwarf.blue</groupId>
  43 + <artifactId>capedwarf-common</artifactId>
  44 + </dependency>
  45 +
  46 + <dependency>
  47 + <groupId>com.google.appengine</groupId>
  48 + <artifactId>appengine-api-1.0-sdk</artifactId>
  49 + </dependency>
  50 +
  51 + <dependency>
  52 + <groupId>org.jboss.spec.javax.servlet</groupId>
  53 + <artifactId>jboss-servlet-api_3.0_spec</artifactId>
  54 + <scope>provided</scope>
  55 + </dependency>
  56 +
  57 + <dependency>
  58 + <groupId>org.jboss.arquillian.junit</groupId>
  59 + <artifactId>arquillian-junit-container</artifactId>
  60 + <scope>test</scope>
  61 + </dependency>
  62 +
  63 + <dependency>
  64 + <groupId>org.jboss.as</groupId>
  65 + <artifactId>jboss-as-arquillian-container-remote</artifactId>
  66 + <scope>test</scope>
  67 + </dependency>
  68 +
  69 + <dependency>
  70 + <groupId>org.jboss.arquillian.protocol</groupId>
  71 + <artifactId>arquillian-protocol-servlet</artifactId>
  72 + <scope>test</scope>
  73 + </dependency>
  74 +
  75 + <dependency>
  76 + <groupId>junit</groupId>
  77 + <artifactId>junit</artifactId>
  78 + <scope>test</scope>
  79 + </dependency>
  80 +
  81 + </dependencies>
  82 +
  83 +</project>
229 log/src/main/java/org/jboss/capedwarf/log/CapedwarfLogService.java
... ... @@ -0,0 +1,229 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.capedwarf.log;
  24 +
  25 +import com.google.appengine.api.datastore.DatastoreServiceFactory;
  26 +import com.google.appengine.api.datastore.Entity;
  27 +import com.google.appengine.api.datastore.FetchOptions;
  28 +import com.google.appengine.api.datastore.Key;
  29 +import com.google.appengine.api.datastore.Query;
  30 +import com.google.appengine.api.log.AppLogLine;
  31 +import com.google.appengine.api.log.LogQuery;
  32 +import com.google.appengine.api.log.LogService;
  33 +import com.google.appengine.api.log.RequestLogs;
  34 +import com.google.apphosting.api.ApiProxy;
  35 +import org.jboss.capedwarf.common.apiproxy.JBossDelegate;
  36 +
  37 +import javax.servlet.ServletRequest;
  38 +import javax.servlet.http.HttpServletRequest;
  39 +import java.util.ArrayList;
  40 +import java.util.HashMap;
  41 +import java.util.Iterator;
  42 +import java.util.List;
  43 +import java.util.Map;
  44 +import java.util.logging.Level;
  45 +import java.util.logging.LogRecord;
  46 +
  47 +/**
  48 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
  49 + */
  50 +public class CapedwarfLogService implements LogService {
  51 +
  52 + private static final String LOG_REQUEST_ENTITY_KIND = "__org.jboss.capedwarf.LogRequest__";
  53 + private static final String LOG_REQUEST_START_TIME_MILLIS = "startTimeMillis";
  54 + private static final String LOG_REQUEST_END_TIME_MILLIS = "endTimeMillis";
  55 + private static final String LOG_REQUEST_URI = "uri";
  56 + private static final String LOG_REQUEST_USER_AGENT = "userAgent";
  57 +
  58 + private static final String LOG_LINE_ENTITY_KIND = "__org.jboss.capedwarf.LogLine__";
  59 + private static final String LOG_LINE_REQUEST_KEY = "requestKey";
  60 + private static final String LOG_LINE_MILLIS = "millis";
  61 + private static final String LOG_LINE_LEVEL = "level";
  62 + private static final String LOG_LINE_MESSAGE = "message";
  63 + private static final String LOG_LINE_LOGGER = "logger";
  64 + private static final String LOG_LINE_THROWN = "thrown";
  65 +
  66 + private static final String LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE = "__org.jboss.capedwarf.LogRequest__";
  67 +
  68 +
  69 + public Iterable<RequestLogs> fetch(LogQuery logQuery) {
  70 + List<RequestLogs> list = new ArrayList<RequestLogs>();
  71 +
  72 + Map<Key, RequestLogs> map = fetchRequestLogs(logQuery, list);
  73 + fetchAppLogLines(logQuery, map);
  74 + if (logQuery.getMinLogLevel() != null) {
  75 + removeRequestsWithNoLogLines(list);
  76 + }
  77 + return list;
  78 + }
  79 +
  80 + private void removeRequestsWithNoLogLines(List<RequestLogs> list) {
  81 + for (Iterator<RequestLogs> iterator = list.iterator(); iterator.hasNext(); ) {
  82 + RequestLogs requestLogs = iterator.next();
  83 + if (requestLogs.getAppLogLines().isEmpty()) {
  84 + iterator.remove();
  85 + }
  86 + }
  87 + }
  88 +
  89 + private Map<Key, RequestLogs> fetchRequestLogs(LogQuery logQuery, List<RequestLogs> list) {
  90 + Map<Key, RequestLogs> map = new HashMap<Key, RequestLogs>();
  91 +
  92 + Query query = createRequestLogsQuery(logQuery);
  93 + FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
  94 +
  95 + List<Entity> entities = DatastoreServiceFactory.getDatastoreService().prepare(query).asList(fetchOptions);
  96 + for (Entity entity : entities) {
  97 + RequestLogs requestLogs = new RequestLogs();
  98 + Long startTimeUsec = (Long) entity.getProperty(LOG_REQUEST_START_TIME_MILLIS);
  99 + if (startTimeUsec != null) {
  100 + requestLogs.setStartTimeUsec(startTimeUsec);
  101 + }
  102 + Long endTimeUsec = (Long) entity.getProperty(LOG_REQUEST_END_TIME_MILLIS);
  103 + if (endTimeUsec == null) {
  104 + requestLogs.setFinished(false);
  105 + } else {
  106 + requestLogs.setEndTimeUsec(endTimeUsec);
  107 + requestLogs.setPendingTime(requestLogs.getEndTimeUsec() - requestLogs.getStartTimeUsec());
  108 + }
  109 + requestLogs.setResource((String) entity.getProperty(LOG_REQUEST_URI));
  110 + requestLogs.setUserAgent((String) entity.getProperty(LOG_REQUEST_USER_AGENT));
  111 + // TODO: set all other properties
  112 +
  113 + map.put(entity.getKey(), requestLogs);
  114 + list.add(requestLogs);
  115 + }
  116 + return map;
  117 + }
  118 +
  119 + private Query createRequestLogsQuery(LogQuery logQuery) {
  120 + Query query = new Query(LOG_REQUEST_ENTITY_KIND);
  121 + if (logQuery.getStartTimeUsec() != null) {
  122 + query.addFilter(LOG_REQUEST_END_TIME_MILLIS, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getStartTimeUsec());
  123 + }
  124 + if (logQuery.getEndTimeUsec() != null) {
  125 + query.addFilter(LOG_REQUEST_END_TIME_MILLIS, Query.FilterOperator.LESS_THAN_OR_EQUAL, logQuery.getEndTimeUsec());
  126 + }
  127 + query.addSort(LOG_REQUEST_END_TIME_MILLIS);
  128 + return query;
  129 + }
  130 +
  131 + private void fetchAppLogLines(LogQuery logQuery, Map<Key, RequestLogs> map) {
  132 + Query query = createAppLogLinesQuery(logQuery);
  133 + FetchOptions fetchOptions = createAppLogFetchOptions(logQuery);
  134 +
  135 + List<Entity> entities = DatastoreServiceFactory.getDatastoreService().prepare(query).asList(fetchOptions);
  136 + for (Entity entity : entities) {
  137 + AppLogLine logLine = new AppLogLine();
  138 + logLine.setLogLevel(LogLevel.values()[(Integer) entity.getProperty(LOG_LINE_LEVEL)]);
  139 + logLine.setLogMessage((String) entity.getProperty(LOG_LINE_MESSAGE));
  140 + logLine.setTimeUsec((Long) entity.getProperty(LOG_LINE_MILLIS));
  141 +
  142 + RequestLogs requestLogs = map.get((Key) entity.getProperty(LOG_LINE_REQUEST_KEY));
  143 + requestLogs.getAppLogLines().add(logLine);
  144 + }
  145 + }
  146 +
  147 + private Query createAppLogLinesQuery(LogQuery logQuery) {
  148 + Query query = new Query(LOG_LINE_ENTITY_KIND);
  149 + if (logQuery.getMinLogLevel() != null) {
  150 + query.addFilter(LOG_LINE_LEVEL, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getMinLogLevel().ordinal());
  151 + }
  152 + if (logQuery.getStartTimeUsec() != null) {
  153 + query.addFilter(LOG_LINE_MILLIS, Query.FilterOperator.GREATER_THAN_OR_EQUAL, logQuery.getStartTimeUsec());
  154 + }
  155 + if (logQuery.getEndTimeUsec() != null) {
  156 + query.addFilter(LOG_LINE_MILLIS, Query.FilterOperator.LESS_THAN_OR_EQUAL, logQuery.getEndTimeUsec());
  157 + }
  158 + query.addSort(LOG_LINE_MILLIS);
  159 + return query;
  160 + }
  161 +
  162 + private FetchOptions createAppLogFetchOptions(LogQuery logQuery) {
  163 + FetchOptions fetchOptions = FetchOptions.Builder.withDefaults();
  164 + if (logQuery.getBatchSize() != null) {
  165 + fetchOptions = fetchOptions.limit(logQuery.getBatchSize());
  166 + }
  167 + return fetchOptions;
  168 + }
  169 +
  170 + public void log(LogRecord record) {
  171 + JBossDelegate jBossDelegate = (JBossDelegate) ApiProxy.getDelegate();
  172 + ServletRequest request = jBossDelegate.getServletRequest();
  173 +
  174 + Entity entity = new Entity(LOG_LINE_ENTITY_KIND);
  175 + entity.setProperty(LOG_LINE_LOGGER, record.getLoggerName());
  176 + entity.setProperty(LOG_LINE_LEVEL, getLogLevel(record).ordinal());
  177 + entity.setProperty(LOG_LINE_MILLIS, record.getMillis());
  178 + entity.setProperty(LOG_LINE_THROWN, record.getThrown());
  179 + entity.setProperty(LOG_LINE_MESSAGE, record.getMessage()); // TODO: format message
  180 + entity.setProperty(LOG_LINE_REQUEST_KEY, getRequestEntityKey(request));
  181 + DatastoreServiceFactory.getAsyncDatastoreService().put(entity);
  182 + }
  183 +
  184 + private LogLevel getLogLevel(LogRecord record) {
  185 + // TODO
  186 + if (record.getLevel().equals(Level.INFO)) {
  187 + return LogLevel.INFO;
  188 + } else if (record.getLevel().equals(Level.WARNING)) {
  189 + return LogLevel.WARN;
  190 + } else if (record.getLevel().equals(Level.SEVERE)) {
  191 + return LogLevel.ERROR;
  192 + } else if (record.getLevel().equals(Level.FINE)) {
  193 + return LogLevel.DEBUG;
  194 + } else {
  195 + return LogLevel.INFO;
  196 + }
  197 + }
  198 +
  199 + public void requestStarted(ServletRequest servletRequest, long startTimeMillis) {
  200 + Entity entity = new Entity(LOG_REQUEST_ENTITY_KIND);
  201 + entity.setProperty(LOG_REQUEST_START_TIME_MILLIS, startTimeMillis);
  202 +
  203 + if (servletRequest instanceof HttpServletRequest) {
  204 + HttpServletRequest request = (HttpServletRequest) servletRequest;
  205 + entity.setProperty(LOG_REQUEST_URI, request.getRequestURI());
  206 + entity.setProperty(LOG_REQUEST_USER_AGENT, request.getHeader("User-Agent"));
  207 + }
  208 +
  209 + DatastoreServiceFactory.getDatastoreService().put(entity);
  210 + servletRequest.setAttribute(LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE, entity);
  211 + }
  212 +
  213 + public void requestFinished(ServletRequest servletRequest) {
  214 + Entity entity = getRequestEntity(servletRequest);
  215 + entity.setProperty(LOG_REQUEST_END_TIME_MILLIS, System.currentTimeMillis());
  216 +
  217 +// HttpServletResponse response;
  218 + // TODO entity.setProperty("responseStatusCode", response.getStatus());
  219 + // TODO entity.setProperty("responseLength", );
  220 + }
  221 +
  222 + private Entity getRequestEntity(ServletRequest request) {
  223 + return (Entity) request.getAttribute(LOG_REQUEST_ENTITY_REQUEST_ATTRIBUTE);
  224 + }
  225 +
  226 + private Key getRequestEntityKey(ServletRequest request) {
  227 + return getRequestEntity(request).getKey();
  228 + }
  229 +}
7 ...va/org/jboss/capedwarf/common/logging/Logger.java → ...src/main/java/org/jboss/capedwarf/log/Logger.java
@@ -20,7 +20,9 @@
20 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 21 */
22 22
23   -package org.jboss.capedwarf.common.logging;
  23 +package org.jboss.capedwarf.log;
  24 +
  25 +import com.google.appengine.api.log.LogServiceFactory;
24 26
25 27 import java.util.logging.LogRecord;
26 28
@@ -28,10 +30,11 @@
28 30 * Logger.
29 31 *
30 32 * @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
  33 + * @author <a href="mailto:marko.luksa@gmail.com">Marko Luksa</a>
31 34 */
32 35 public class Logger {
33 36 public static void publish(LogRecord record) {
34   - // TODO
  37 + ((CapedwarfLogService)LogServiceFactory.getLogService()).log(record);
35 38 }
36 39
37 40 public static void flush() {
73 log/src/test/java/org/jboss/test/capedwarf/log/LoggingTest.java
... ... @@ -0,0 +1,73 @@
  1 +/*
  2 + * JBoss, Home of Professional Open Source.
  3 + * Copyright 2012, Red Hat, Inc., and individual contributors
  4 + * as indicated by the @author tags. See the copyright.txt file in the
  5 + * distribution for a full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.jboss.test.capedwarf.log;
  24 +
  25 +import com.google.appengine.api.log.AppLogLine;
  26 +import com.google.appengine.api.log.LogQuery;
  27 +import com.google.appengine.api.log.LogServiceFactory;
  28 +import com.google.appengine.api.log.RequestLogs;
  29 +import org.jboss.arquillian.container.test.api.Deployment;
  30 +import org.jboss.arquillian.junit.Arquillian;
  31 +import org.jboss.shrinkwrap.api.Archive;
  32 +import org.jboss.shrinkwrap.api.ShrinkWrap;
  33 +import org.jboss.shrinkwrap.api.asset.StringAsset;
  34 +import org.jboss.shrinkwrap.api.spec.WebArchive;
  35 +import org.junit.Assert;
  36 +import org.junit.Test;
  37 +import org.junit.runner.RunWith;
  38 +
  39 +import java.util.List;
  40 +import java.util.logging.Logger;
  41 +
  42 +/**
  43 + *
  44 + */
  45 +@RunWith(Arquillian.class)
  46 +public class LoggingTest {
  47 +
  48 + @Deployment
  49 + public static Archive getDeployment() {
  50 + return ShrinkWrap.create(WebArchive.class)
  51 + .setWebXML(new StringAsset("<web/>"))
  52 + .addAsWebInfResource("appengine-web.xml");
  53 + }
  54 +
  55 + @Test
  56 + public void testLogging() {
  57 + Logger log = Logger.getLogger("TestLogger");
  58 + log.info("hello");
  59 +
  60 + Iterable<RequestLogs> iterable = LogServiceFactory.getLogService().fetch(new LogQuery());
  61 + Assert.assertTrue(iterable.iterator().hasNext());
  62 +
  63 + for (RequestLogs requestLogs : iterable) {
  64 + List<AppLogLine> appLogLines = requestLogs.getAppLogLines();
  65 + for (AppLogLine appLogLine : appLogLines) {
  66 + if ("hello".equals(appLogLine.getLogMessage())) {
  67 + return; // test passes
  68 + }
  69 + }
  70 + }
  71 + Assert.fail("Did not find 'hello' in logs.");
  72 + }
  73 +}
27 log/src/test/resources/appengine-web.xml
... ... @@ -0,0 +1,27 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!--
  3 + ~ JBoss, Home of Professional Open Source.
  4 + ~ Copyright 2012, Red Hat, Inc., and individual contributors
  5 + ~ as indicated by the @author tags. See the copyright.txt file in the
  6 + ~ distribution for a full listing of individual contributors.
  7 + ~
  8 + ~ This is free software; you can redistribute it and/or modify it
  9 + ~ under the terms of the GNU Lesser General Public License as
  10 + ~ published by the Free Software Foundation; either version 2.1 of
  11 + ~ the License, or (at your option) any later version.
  12 + ~
  13 + ~ This software is distributed in the hope that it will be useful,
  14 + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + ~ Lesser General Public License for more details.
  17 + ~
  18 + ~ You should have received a copy of the GNU Lesser General Public
  19 + ~ License along with this software; if not, write to the Free
  20 + ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21 + ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  22 + -->
  23 +
  24 +<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  25 + <application>test</application>
  26 + <version>1</version>
  27 +</appengine-web-app>
30 log/src/test/resources/arquillian.xml
... ... @@ -0,0 +1,30 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!--
  3 + ~ JBoss, Home of Professional Open Source.
  4 + ~ Copyright 2012, Red Hat, Inc., and individual contributors
  5 + ~ as indicated by the @author tags. See the copyright.txt file in the
  6 + ~ distribution for a full listing of individual contributors.
  7 + ~
  8 + ~ This is free software; you can redistribute it and/or modify it
  9 + ~ under the terms of the GNU Lesser General Public License as
  10 + ~ published by the Free Software Foundation; either version 2.1 of
  11 + ~ the License, or (at your option) any later version.
  12 + ~
  13 + ~ This software is distributed in the hope that it will be useful,
  14 + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + ~ Lesser General Public License for more details.
  17 + ~
  18 + ~ You should have received a copy of the GNU Lesser General Public
  19 + ~ License along with this software; if not, write to the Free
  20 + ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21 + ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  22 + -->
  23 +
  24 +<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  25 + xmlns="http://jboss.org/schema/arquillian"
  26 + xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
  27 +
  28 + <defaultProtocol type="Servlet 3.0"/>
  29 +
  30 +</arquillian>
7 pom.xml
@@ -29,6 +29,7 @@
29 29 <module>environment</module>
30 30 <module>files</module>
31 31 <module>images</module>
  32 + <module>log</module>
32 33 <module>mail</module>
33 34 <module>memcache</module>
34 35 <module>multitenancy</module>
@@ -282,6 +283,12 @@
282 283
283 284 <dependency>
284 285 <groupId>org.jboss.capedwarf.blue</groupId>
  286 + <artifactId>capedwarf-log</artifactId>
  287 + <version>${project.version}</version>
  288 + </dependency>
  289 +
  290 + <dependency>
  291 + <groupId>org.jboss.capedwarf.blue</groupId>
285 292 <artifactId>capedwarf-mail</artifactId>
286 293 <version>${project.version}</version>
287 294 </dependency>

0 comments on commit 5dd5875

Please sign in to comment.
Something went wrong with that request. Please try again.