You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2013/12/02 16:04:46 UTC
[2/2] git commit: Wrapping up and adding S3 functionality
Wrapping up and adding S3 functionality
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/ddf0f355
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/ddf0f355
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/ddf0f355
Branch: refs/heads/two-dot-o
Commit: ddf0f35573bdfe4fef8859c2fb4513aa36a1df6d
Parents: a022fb1
Author: Alex Karasulu <ak...@apache.org>
Authored: Mon Dec 2 16:06:10 2013 +0200
Committer: Dave Johnson <dm...@apigee.com>
Committed: Mon Dec 2 09:59:37 2013 -0500
----------------------------------------------------------------------
stack/corepersistence/perftest/pom.xml | 109 +++++++++--
.../org/apache/usergrid/perftest/CallStats.java | 117 +++++++++++
.../usergrid/perftest/PerftestRunnerTest.java | 31 +++
.../apache/usergrid/perftest/ResultsLog.java | 51 +++++
.../usergrid/perftest/ResultsLogImpl.java | 133 +++++++++++++
.../perftest/amazon/AmazonS3Module.java | 15 ++
.../perftest/amazon/AmazonS3Service.java | 24 +++
.../perftest/amazon/AmazonS3ServiceImpl.java | 196 +++++++++++++++++++
.../apache/usergrid/perftest/logging/Log.java | 19 --
.../perftest/logging/Slf4jMembersInjector.java | 46 -----
.../perftest/logging/Slf4jTypeListener.java | 44 -----
.../usergrid/perfteststats/CallStats.java | 90 ---------
.../src/main/resources/config.properties | 11 +-
.../src/main/resources/log4j.properties | 18 +-
.../usergrid/perftest/ResultsLogImplTest.java | 82 ++++++++
.../perftest/amazon/AmazonS3ServiceTest.java | 39 ++++
.../src/test/resources/log4j-jetty.properties | 9 +
.../src/test/resources/log4j.properties | 9 +
18 files changed, 816 insertions(+), 227 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/pom.xml
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/pom.xml b/stack/corepersistence/perftest/pom.xml
index b5c70ee..63adbf1 100644
--- a/stack/corepersistence/perftest/pom.xml
+++ b/stack/corepersistence/perftest/pom.xml
@@ -15,8 +15,9 @@
<properties>
<slf4j.version>1.6.1</slf4j.version>
+ <jclouds.version>1.6.2-incubating</jclouds.version>
<blitz4j.version>1.31</blitz4j.version>
- <archaius.version>0.4.1</archaius.version>
+ <archaius.version>0.5.12</archaius.version>
<servo.version>0.4.36</servo.version>
<jersey.version>1.9.1</jersey.version>
<jackson.version>2.1.5</jackson.version>
@@ -31,12 +32,50 @@
<build>
<finalName>${pom.artifactId}</finalName>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </resource>
+ </resources>
+
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </testResource>
+ </testResources>
+
<plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <classes.base>${project.build.outputDirectory}</classes.base>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.plugin.version}</version>
<configuration>
+ <systemProperties>
+ <systemProperty>
+ <name>log4j.configuration</name>
+ <value>file:///${project.build.testOutputDirectory}/log4j-jetty.properties</value>
+ </systemProperty>
+ </systemProperties>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
@@ -48,6 +87,48 @@
<dependencies>
<dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-blobstore</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-core</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-allblobstore</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds.driver</groupId>
+ <artifactId>jclouds-netty</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds.driver</groupId>
+ <artifactId>jclouds-apachehc</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds.driver</groupId>
+ <artifactId>jclouds-log4j</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.jclouds.driver</groupId>
+ <artifactId>jclouds-slf4j</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
@@ -78,6 +159,12 @@
</dependency>
<dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>15.0</version>
+ </dependency>
+
+ <dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
<version>${guice.version}</version>
@@ -120,6 +207,12 @@
</dependency>
<dependency>
+ <groupId>com.netflix.archaius</groupId>
+ <artifactId>archaius-jclouds</artifactId>
+ <version>${archaius.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
@@ -129,22 +222,16 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
- <exclusions>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- </exclusions>
</dependency>
<!-- Test RelatedDependencies -->
<dependency>
- <groupId>com.google.guiceberry</groupId>
- <artifactId>guiceberry</artifactId>
- <version>3.3.1</version>
- <scope>test</scope>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
</dependency>
+
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/CallStats.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/CallStats.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/CallStats.java
new file mode 100644
index 0000000..1474b08
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/CallStats.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.usergrid.perftest;
+
+
+import com.google.inject.Inject;
+import org.apache.usergrid.perftest.rest.CallStatsSnapshot;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+/**
+ * Atomically stores and updates call statistics on tests.
+ */
+public class CallStats {
+ private static final Logger LOG = LoggerFactory.getLogger( CallStats.class );
+
+ private final AtomicInteger callCount = new AtomicInteger();
+ private final Object lock = new Object();
+ private final TimeUnit units = TimeUnit.NANOSECONDS;
+ private ResultsLog log;
+
+ private long maxTime = Long.MIN_VALUE;
+ private long minTime = Long.MAX_VALUE;
+ private long meanTime = 0;
+ private long totalTime = 0;
+
+
+ @Inject
+ public void setResultsLog( ResultsLog log ) {
+ this.log = log;
+ try {
+ log.open();
+ }
+ catch ( IOException e ) {
+ LOG.error( "Failed to open the results log.", e );
+ }
+ }
+
+
+ public int getCallCount() {
+ synchronized ( lock ) {
+ return callCount.get();
+ }
+ }
+
+
+ public CallStatsSnapshot getStatsSnapshot( boolean isRunning, long startTime, long stopTime ) {
+ synchronized ( lock )
+ {
+ return new CallStatsSnapshot( callCount.get(), maxTime, minTime, meanTime, isRunning, startTime, stopTime );
+ }
+ }
+
+
+ public int callOccurred( Perftest test, long startTime, long endTime, TimeUnit units )
+ {
+ synchronized ( lock ) {
+ if ( callCount.get() > test.getCallCount() - 1 ) {
+ return callCount.get();
+ }
+
+ if ( this.units.equals( units ) ) {
+ long time = endTime - startTime;
+
+ totalTime += time;
+ maxTime = Math.max( maxTime, time );
+ minTime = Math.min( minTime, time );
+ int numCalls = callCount.incrementAndGet();
+ StringBuilder sb = new StringBuilder();
+ sb.append( numCalls ).append( " " ).append( startTime ).append( " " ).append( endTime );
+ log.write(sb.toString());
+ meanTime = totalTime / numCalls;
+ return numCalls;
+ }
+ else {
+ throw new RuntimeException( "Time unit corrections have not been implemented." );
+ }
+ }
+ }
+
+
+ public void stop() {
+ log.close();
+ }
+
+
+ public void reset() {
+ try {
+ log.truncate();
+ }
+ catch ( IOException e ) {
+ LOG.error( "Failed to truncate the results file.", e );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/PerftestRunnerTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/PerftestRunnerTest.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/PerftestRunnerTest.java
new file mode 100644
index 0000000..400260e
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/PerftestRunnerTest.java
@@ -0,0 +1,31 @@
+package org.apache.usergrid.perftest;
+
+import com.google.inject.Guice;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class PerftestRunnerTest {
+ @Test
+ public void testPerftestRunner() throws InterruptedException {
+ PerftestRunner runner = Guice.createInjector( new PerftestModule() ).getInstance( PerftestRunner.class );
+ assertFalse( runner.isRunning() );
+
+ runner.start();
+ assertTrue( runner.isRunning() );
+
+ while ( runner.isRunning() )
+ {
+ Thread.sleep( 100 );
+ }
+
+ runner.stop();
+ assertFalse( runner.isRunning() );
+
+ assertEquals( 1000, runner.getCallStatsSnapshot().getCallCount() );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLog.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLog.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLog.java
new file mode 100644
index 0000000..75302d0
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLog.java
@@ -0,0 +1,51 @@
+package org.apache.usergrid.perftest;
+
+import java.io.IOException;
+
+/**
+ * Logs results as they are produced asynchronously.
+ */
+public interface ResultsLog {
+ String RESULTS_FILE_KEY = "resultsLog.file";
+ String WAIT_TIME_KEY = "resultsLog.waitTime";
+
+ /**
+ * Opens the result log.
+ *
+ * @throws IOException on failures to open the results log file.
+ */
+ void open() throws IOException;
+
+
+ /**
+ * Closes the result log which also causes a flush.
+ */
+ void close();
+
+
+ /**
+ * Truncates the results effectively deleting previous captures.
+ *
+ * @throws IOException if there are issues truncating the log file.
+ */
+ void truncate() throws IOException;
+
+
+ /**
+ * Writes a result record into the log.
+ *
+ * @param result the result to log.
+ */
+ void write( String result );
+
+
+ /**
+ * Gets the number of results recorded by the log.
+ *
+ * @return the number of results.
+ */
+ long getResultCount();
+
+
+ String getPath();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLogImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLogImpl.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLogImpl.java
new file mode 100644
index 0000000..b7c46d4
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/ResultsLogImpl.java
@@ -0,0 +1,133 @@
+package org.apache.usergrid.perftest;
+
+import com.netflix.config.DynamicLongProperty;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.config.DynamicStringProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.channels.FileChannel;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+/**
+ * An asynchronous results log implementation.
+ */
+public class ResultsLogImpl implements ResultsLog, Runnable {
+ private static final Logger LOG = LoggerFactory.getLogger( ResultsLogImpl.class );
+
+ private final AtomicLong resultCount = new AtomicLong();
+ private final AtomicBoolean isOpen = new AtomicBoolean( false );
+ private LinkedBlockingDeque<String> buffer = new LinkedBlockingDeque<String>();
+ private PrintWriter out;
+ private Thread thread;
+
+ private DynamicStringProperty resultsFile;
+ private DynamicLongProperty waitTime;
+
+
+ public ResultsLogImpl() {
+ String defaultFile = "/tmp/perftest_results.log";
+
+ resultsFile = DynamicPropertyFactory.getInstance().getStringProperty( RESULTS_FILE_KEY, defaultFile );
+ waitTime = DynamicPropertyFactory.getInstance().getLongProperty( WAIT_TIME_KEY, 200 );
+ }
+
+
+ @Override
+ public void open() throws IOException {
+ synchronized ( isOpen ) {
+ if ( isOpen.compareAndSet( false, true ) ) {
+ out = new PrintWriter( resultsFile.get() );
+ resultCount.set( 0 );
+ thread = new Thread( this, "ResultLog Writer" );
+ thread.start();
+ }
+ }
+ }
+
+
+ @Override
+ public void close() {
+ if ( isOpen.compareAndSet( true, false ) ) {
+
+ // Forces us to wait until the writer thread dies
+ synchronized ( isOpen ) {
+ out.flush();
+ out.close();
+ thread = null;
+ }
+ }
+ }
+
+
+ @Override
+ public void truncate() throws IOException {
+ if ( isOpen.get() ) {
+ throw new IOException( "Cannot truncate while log is open for writing. Close the log then truncate." );
+ }
+
+ // Synchronize on isOpen to prevent re-opening while truncating (rare)
+ synchronized ( isOpen ) {
+ File results = new File( resultsFile.get() );
+ FileChannel channel = new FileOutputStream( results, true ).getChannel();
+ channel.truncate( 0 );
+ channel.close();
+ resultCount.set( 0 );
+ }
+ }
+
+
+ @Override
+ public void write( String result ) {
+ try {
+ buffer.putFirst( result );
+ }
+ catch ( InterruptedException e ) {
+ LOG.error( "Was interrupted on write.", e );
+ }
+ }
+
+
+ @Override
+ public long getResultCount() {
+ return resultCount.get();
+ }
+
+
+ @Override
+ public String getPath() {
+ return resultsFile.get();
+ }
+
+
+ @Override
+ public void run() {
+ synchronized ( isOpen )
+ {
+ // Keep writing after closed until buffer is flushed (empty)
+ while ( isOpen.get() || ! buffer.isEmpty() ) {
+ try {
+ String result = buffer.pollLast( waitTime.get(), TimeUnit.MILLISECONDS );
+
+ if ( result != null ) {
+ resultCount.incrementAndGet();
+ out.println( result );
+ }
+ }
+ catch ( InterruptedException e ) {
+ LOG.error( "ResultLog thread interrupted.", e );
+ }
+ }
+
+ isOpen.notifyAll();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Module.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Module.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Module.java
new file mode 100644
index 0000000..2d38c9f
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Module.java
@@ -0,0 +1,15 @@
+/*
+ * Created by IntelliJ IDEA.
+ * User: akarasulu
+ * Date: 12/2/13
+ * Time: 3:17 AM
+ */
+package org.apache.usergrid.perftest.amazon;
+
+import com.google.inject.AbstractModule;
+
+public class AmazonS3Module extends AbstractModule {
+ protected void configure() {
+ bind( AmazonS3Service.class ).to( AmazonS3ServiceImpl.class ).asEagerSingleton();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Service.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Service.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Service.java
new file mode 100644
index 0000000..7b40c2c
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3Service.java
@@ -0,0 +1,24 @@
+package org.apache.usergrid.perftest.amazon;
+
+/**
+ * The S3 Service is used to register the node so other nodes in the same
+ * perftest formation can access it.
+ */
+public interface AmazonS3Service {
+ String AWS_BUCKET_KEY = "aws.s3.bucket";
+ String AWS_KEY = "aws.s3.key";
+ String AWS_SECRET = "aws.s3.secret";
+ String FORMATION_KEY = "perftest.formation";
+ String ARCHAIUS_CONTAINER_KEY = "com.netflix.config.blobstore.containerName";
+ String PUBLIC_HOSTNAME_KEY = "public-hostname";
+ String LOCAL_HOSTNAME_KEY = "local-hostname";
+ String PUBLIC_IPV4_KEY = "public-ipv4";
+ String LOCAL_IPV4_KEY = "local-ipv4";
+ String INSTANCE_URL = "http://169.254.169.254/latest/meta-data";
+
+ void start();
+
+ boolean isStarted();
+
+ void stop();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceImpl.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceImpl.java
new file mode 100644
index 0000000..44643fe
--- /dev/null
+++ b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceImpl.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.usergrid.perftest.amazon;
+
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import com.google.inject.Singleton;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.config.DynamicStringProperty;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.jclouds.ContextBuilder;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.BlobBuilder;
+import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
+import org.jclouds.logging.log4j.config.Log4JLoggingModule;
+import org.jclouds.netty.config.NettyPayloadModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+
+/**
+ * Sets up the S3 configuration if running in EC2.
+ */
+@Singleton
+public class AmazonS3ServiceImpl implements AmazonS3Service {
+
+ private final static Logger LOG = LoggerFactory.getLogger( AmazonS3ServiceImpl.class );
+ private final static String DEFAULT_CONTAINER = "perftest-bucket";
+ private static final Iterable<? extends Module> MODULES = ImmutableSet.of(
+ new JavaUrlHttpCommandExecutorServiceModule(),
+ new Log4JLoggingModule(),
+ new NettyPayloadModule() );
+
+ private DynamicStringProperty perftestFormation;
+
+ private BlobStoreContext context;
+ private boolean started = false;
+ private String publicHostname;
+ private String publicIpv4;
+ private String localHostname;
+ private String localIpv4;
+ private String blobName;
+ private DynamicStringProperty s3bucket;
+ private DynamicStringProperty s3key;
+ private DynamicStringProperty s3secret;
+
+
+ public AmazonS3ServiceImpl()
+ {
+ s3bucket =
+ DynamicPropertyFactory.getInstance().getStringProperty( AWS_BUCKET_KEY, DEFAULT_CONTAINER );
+ s3key =
+ DynamicPropertyFactory.getInstance().getStringProperty( AWS_KEY, "bogus" );
+ s3secret =
+ DynamicPropertyFactory.getInstance().getStringProperty( AWS_SECRET, "bogus" );
+ perftestFormation =
+ DynamicPropertyFactory.getInstance().getStringProperty( FORMATION_KEY, "default" );
+ }
+
+
+ @Override
+ public void start()
+ {
+ if ( ! initialize() )
+ {
+ started = false;
+ return;
+ }
+
+ System.setProperty( ARCHAIUS_CONTAINER_KEY, s3bucket.get() );
+ started = true;
+ }
+
+
+ @Override
+ public boolean isStarted()
+ {
+ return started;
+ }
+
+
+ @Override
+ public void stop()
+ {
+ if ( isStarted() && context != null )
+ {
+ BlobStore blobStore = context.getBlobStore();
+ blobStore.removeBlob( s3bucket.get(), blobName );
+ context.close();
+ }
+ }
+
+
+ private boolean initialize()
+ {
+ if ( ! populateEc2Metadata() )
+ {
+ LOG.warn( "We're not running in EC2! Node registration would not succeed." );
+ return false;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append( perftestFormation.get() ).append( '_' ).append( publicHostname );
+ this.blobName = sb.toString();
+
+ sb = new StringBuilder();
+ sb.append( FORMATION_KEY ).append( '=' ).append( perftestFormation.get() ).append( "\n" );
+ sb.append( PUBLIC_HOSTNAME_KEY ).append( '=' ).append( publicHostname ).append("\n");
+ sb.append( LOCAL_HOSTNAME_KEY ).append( '=' ).append( localHostname ).append( "\n" );
+ sb.append( PUBLIC_IPV4_KEY ).append( '=' ).append( publicIpv4 ).append( "\n" );
+ sb.append( LOCAL_IPV4_KEY ).append( '=' ).append( localIpv4 ).append( "\n" );
+
+ context = ContextBuilder.newBuilder( "aws-s3" )
+ .credentials( s3key.get(), s3secret.get() )
+ .modules( MODULES )
+ .buildView( BlobStoreContext.class );
+
+ BlobStore blobStore = context.getBlobStore();
+ BlobBuilder builder = blobStore.blobBuilder( this.blobName ).payload( sb.toString() );
+ Blob blob = builder.build();
+ String blobUuid = context.getBlobStore().putBlob( DEFAULT_CONTAINER, blob );
+ LOG.info( "Successfully registered {} with UUID = {}", this.blobName, blobUuid );
+
+ return true;
+ }
+
+
+ private boolean populateEc2Metadata()
+ {
+ try {
+ this.publicHostname = extractEc2Metadata( PUBLIC_HOSTNAME_KEY );
+ this.localHostname = extractEc2Metadata( LOCAL_HOSTNAME_KEY );
+ this.publicIpv4 = extractEc2Metadata( PUBLIC_IPV4_KEY );
+ this.localIpv4 = extractEc2Metadata( LOCAL_IPV4_KEY );
+ return true;
+ }
+ catch ( IOException ioe ) {
+ return false;
+ }
+ }
+
+
+ private String extractEc2Metadata( String data ) throws IOException
+ {
+ StringBuilder url = new StringBuilder();
+ url.append( INSTANCE_URL ).append( '/' ).append( data );
+
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpGet request = new HttpGet( url.toString() );
+
+ try {
+ HttpResponse response = client.execute( request );
+ int statusCode = response.getStatusLine().getStatusCode();
+
+ if ( statusCode == 200 ) {
+ int initCapacity = ( int ) response.getEntity().getContentLength() + 1;
+ ByteArrayOutputStream out = new ByteArrayOutputStream( initCapacity );
+ response.getEntity().writeTo( out );
+ out.flush();
+ out.close();
+ return out.toString();
+ }
+
+ throw new IOException( "Got bad status " + statusCode + " for URL " + url );
+ }
+ catch ( IOException ioe ) {
+ LOG.error( "Failed to extract {} from {}", data, url );
+ throw ioe;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Log.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Log.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Log.java
deleted file mode 100644
index 32ddfee..0000000
--- a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Log.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.apache.usergrid.perftest.logging;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-/**
- * Annotation to use to inject a SLF4J Logger backed by Log4j.
- */
-@Scope
-@Documented
-@Retention( RUNTIME )
-@Target( FIELD )
-public @interface Log {
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jMembersInjector.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jMembersInjector.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jMembersInjector.java
deleted file mode 100644
index 7ccbe7f..0000000
--- a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jMembersInjector.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.usergrid.perftest.logging;
-
-
-import com.google.inject.MembersInjector;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.reflect.Field;
-
-public class Slf4jMembersInjector<T> implements MembersInjector<T> {
- private final Field field;
- private final Logger logger;
-
- public Slf4jMembersInjector(Field field) {
- this.field = field;
- this.logger = LoggerFactory.getLogger(field.getDeclaringClass());
- field.setAccessible(true);
- }
-
- public void injectMembers(T t) {
- try {
- field.set(t, logger);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jTypeListener.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jTypeListener.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jTypeListener.java
deleted file mode 100644
index 7c43bd9..0000000
--- a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perftest/logging/Slf4jTypeListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.usergrid.perftest.logging;
-
-import com.google.inject.TypeLiteral;
-import com.google.inject.spi.TypeEncounter;
-import com.google.inject.spi.TypeListener;
-import org.slf4j.Logger;
-
-import java.lang.reflect.Field;
-
-/**
- * ...
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$
- */
-public class Slf4jTypeListener implements TypeListener {
- public <T> void hear(TypeLiteral<T> typeLiteral, TypeEncounter<T> typeEncounter) {
- for (Field field : typeLiteral.getRawType().getDeclaredFields()) {
- if (field.getType() == Logger.class
- && field.isAnnotationPresent(Log.class)) {
- typeEncounter.register(new Slf4jMembersInjector<T>(field));
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perfteststats/CallStats.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perfteststats/CallStats.java b/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perfteststats/CallStats.java
deleted file mode 100644
index e0a09a0..0000000
--- a/stack/corepersistence/perftest/src/main/java/org/apache/usergrid/perfteststats/CallStats.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.usergrid.perfteststats;
-
-
-import org.apache.usergrid.perftest.Perftest;
-import org.apache.usergrid.perftest.logging.Log;
-import org.apache.usergrid.perftest.rest.CallStatsSnapshot;
-import org.slf4j.Logger;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-
-/**
- * Atomically stores and updates call statistics on tests.
- */
-public class CallStats {
- @Log Logger log;
-
- private final AtomicInteger callCount = new AtomicInteger();
- private final Object lock = new Object();
- private final TimeUnit units = TimeUnit.NANOSECONDS;
-
- private long maxTime = Long.MIN_VALUE;
- private long minTime = Long.MAX_VALUE;
- private long meanTime = 0;
- private long totalTime = 0;
-
-
- public int getCallCount() {
- synchronized ( lock ) {
- return callCount.get();
- }
- }
-
-
- public CallStatsSnapshot getStatsSnapshot( boolean isRunning, long startTime, long stopTime ) {
- synchronized ( lock )
- {
- return new CallStatsSnapshot( callCount.get(), maxTime, minTime, meanTime, isRunning, startTime, stopTime );
- }
- }
-
-
- public int callOccurred( Perftest test, long startTime, long endTime, TimeUnit units )
- {
- synchronized ( lock )
- {
- if ( callCount.get() > test.getCallCount() - 1 )
- {
- return callCount.get();
- }
-
- if ( this.units.equals( units ) ) {
- long time = endTime - startTime;
-
- totalTime += time;
- maxTime = Math.max( maxTime, time );
- minTime = Math.min( minTime, time );
- int numCalls = callCount.incrementAndGet();
- StringBuilder sb = new StringBuilder();
- sb.append( numCalls ).append( " " ).append( startTime ).append( " " ).append( endTime );
- log.debug(sb.toString());
- meanTime = totalTime / numCalls;
- return numCalls;
- }
- else {
- throw new RuntimeException( "Time unit corrections have not been implemented." );
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/resources/config.properties
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/resources/config.properties b/stack/corepersistence/perftest/src/main/resources/config.properties
index f411991..60ddc19 100644
--- a/stack/corepersistence/perftest/src/main/resources/config.properties
+++ b/stack/corepersistence/perftest/src/main/resources/config.properties
@@ -1,6 +1,6 @@
default.call.iterations=10000
default.thread.count=10
-default.configuration.override=simpledb
+#default.configuration.override=simpledb
archaius.deployment.environment=test
archaius.deployment.region=us-east-1c
@@ -18,5 +18,12 @@ archaius.dynamicPropertyFactory.registerConfigWithJMX=true
# Application Settings
test.module.fqcn=org.apache.usergrid.perftest.NoopPerftestModule
-leep.to.stop=100
+sleep.to.stop=100
+# Amazon S3 Settings For Properties
+
+log4j.configuration=file://${catalina.home}/webapps/perftest/WEB-INF/classes/log4j.configuration
+aws.s3.bucket=${aws.s3.bucket}
+aws.s3.key=${aws.s3.key}
+aws.s3.secret=${aws.s3.secret}
+perftest.formation=${perftest.formation}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/main/resources/log4j.properties b/stack/corepersistence/perftest/src/main/resources/log4j.properties
index a114a72..0337723 100644
--- a/stack/corepersistence/perftest/src/main/resources/log4j.properties
+++ b/stack/corepersistence/perftest/src/main/resources/log4j.properties
@@ -1,20 +1,8 @@
-log4j.rootLogger=OFF
-log4j.rootCategory=OFF
+log4j.rootLogger=ERROR,stdout
+log4j.rootCategory=ERROR
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c{3}.%M(%L)<%t>- %m%n
-log4j.appender.results=org.apache.log4j.FileAppender
-log4j.appender.results.File=./results.log
-log4j.appender.results.layout=com.netflix.logging.log4jAdapter.NFPatternLayout
-log4j.appender.results.Append=true
-log4j.appender.results.layout.ConversionPattern=%m%n
-log4j.appender.results.Threshold=DEBUG
-
-log4j.logger.asyncAppenders=OFF,results,stdout
-batcher.com.netflix.logging.AsyncAppender.results.waitTimeinMillis=20000
-
-log4j.logger.org.apache.usergrid.perftest=INFO,stdout
-log4j.logger.org.apache.usergrid.perfteststats=DEBUG,results
-
+log4j.logger.org.apache.usergrid.perftest=INFO
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/ResultsLogImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/ResultsLogImplTest.java b/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/ResultsLogImplTest.java
new file mode 100644
index 0000000..8dabd21
--- /dev/null
+++ b/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/ResultsLogImplTest.java
@@ -0,0 +1,82 @@
+package org.apache.usergrid.perftest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * Tests the ResultsLogImpl.
+ */
+public class ResultsLogImplTest {
+ private static final Logger LOG = LoggerFactory.getLogger( ResultsLogImplTest.class );
+ private final AtomicLong resultCount = new AtomicLong();
+ private final ResultsLog resultsLog = new ResultsLogImpl();
+ private ExecutorService executorService;
+ private Runnable runnable;
+
+
+ @Before
+ public void setup() throws IOException {
+ LOG.info( "Setting up with log file {}.", resultsLog.getPath() );
+ executorService = Executors.newFixedThreadPool( 10 );
+ resultsLog.open();
+ runnable = new Runnable() {
+ @Override
+ public void run() {
+ for ( int ii = 0; ii < 1000; ii++ ) {
+ resultsLog.write( "we are writing out a damn record" );
+ resultCount.incrementAndGet();
+ }
+ }
+ };
+ }
+
+
+ @After
+ public void tearDown() throws InterruptedException {
+ if ( ! executorService.isShutdown() || ! executorService.isTerminated() )
+ {
+ executorService.shutdown();
+ executorService.awaitTermination( 1000, TimeUnit.MILLISECONDS );
+ executorService = null;
+ }
+
+ resultsLog.close();
+ resultCount.set( 0 );
+ }
+
+
+ @Test
+ public void testLog() throws InterruptedException, IOException {
+ for ( int ii = 0; ii < 100; ii++ )
+ {
+ executorService.execute( runnable );
+ }
+
+ executorService.awaitTermination( 1000, TimeUnit.MILLISECONDS );
+ resultsLog.close();
+ File file = new File( resultsLog.getPath() );
+ assertTrue( file.exists() );
+ assertTrue( file.length() > 100 );
+ assertEquals( resultCount.get(), resultsLog.getResultCount() );
+ LOG.info( "The length of the result file is {} bytes.", file.length() );
+
+ resultsLog.truncate();
+ file = new File( resultsLog.getPath() );
+ LOG.info("The length of the result file after truncating is {} bytes.", file.length());
+ assertTrue( file.length() == 0 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceTest.java b/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceTest.java
new file mode 100644
index 0000000..c00f264
--- /dev/null
+++ b/stack/corepersistence/perftest/src/test/java/org/apache/usergrid/perftest/amazon/AmazonS3ServiceTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.usergrid.perftest.amazon;
+
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+
+/**
+ * Tests AmazonS3Service.
+ */
+public class AmazonS3ServiceTest {
+
+ @Test @Ignore
+ public void testSetup() {
+ AmazonS3Service service = new AmazonS3ServiceImpl();
+ service.start();
+ service.isStarted();
+ service.stop();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/test/resources/log4j-jetty.properties
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/test/resources/log4j-jetty.properties b/stack/corepersistence/perftest/src/test/resources/log4j-jetty.properties
new file mode 100644
index 0000000..fe8c6c4
--- /dev/null
+++ b/stack/corepersistence/perftest/src/test/resources/log4j-jetty.properties
@@ -0,0 +1,9 @@
+log4j.rootLogger=DEBUG,stdout
+log4j.rootCategory=DEBUG
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c{3}.%M(%L)<%t>- %m%n
+
+log4j.logger.org.apache.usergrid=DEBUG
+log4j.logger.org.eclipse.jetty=DEBUG
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ddf0f355/stack/corepersistence/perftest/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/stack/corepersistence/perftest/src/test/resources/log4j.properties b/stack/corepersistence/perftest/src/test/resources/log4j.properties
new file mode 100644
index 0000000..232d62e
--- /dev/null
+++ b/stack/corepersistence/perftest/src/test/resources/log4j.properties
@@ -0,0 +1,9 @@
+log4j.rootLogger=ERROR,stdout
+log4j.rootCategory=ERROR
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c{3}.%M(%L)<%t>- %m%n
+
+log4j.logger.org.apache.usergrid.perftest=DEBUG
+