Updated Branches: refs/heads/master a726ca549 -> a455ee706
Fixed BLUR-171. Project: http://git-wip-us.apache.org/repos/asf/incubator-blur/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-blur/commit/a455ee70 Tree: http://git-wip-us.apache.org/repos/asf/incubator-blur/tree/a455ee70 Diff: http://git-wip-us.apache.org/repos/asf/incubator-blur/diff/a455ee70 Branch: refs/heads/master Commit: a455ee7067eb75d5bd7390229992878d16f5a14a Parents: a726ca5 Author: Aaron McCurry <[email protected]> Authored: Sun Jul 21 16:10:45 2013 -0400 Committer: Aaron McCurry <[email protected]> Committed: Sun Jul 21 16:10:45 2013 -0400 ---------------------------------------------------------------------- .../blur/server/ControllerServerContext.java | 71 ++++++++++ .../server/ControllerServerEventHandler.java | 92 ++++++++++++ .../apache/blur/server/ShardServerContext.java | 21 +++ .../blur/server/ShardServerEventHandler.java | 18 ++- .../blur/thrift/ThriftBlurControllerServer.java | 6 +- .../blur/thrift/ThriftBlurShardServer.java | 2 +- .../java/org/apache/blur/utils/BlurUtil.java | 141 ++++++++++++++++++- .../server/TServerEventHandler.java | 3 +- .../thrift_0_9_0/server/TSimpleServer.java | 2 +- .../thrift_0_9_0/server/TThreadPoolServer.java | 2 +- .../server/AbstractNonblockingServer.java | 2 +- .../util/ResetableTByteArrayOutputStream.java | 50 +++++++ .../thrift/util/ResetableTMemoryBuffer.java | 109 ++++++++++++++ distribution/src/main/scripts/conf/log4j.xml | 43 +++++- 14 files changed, 543 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/server/ControllerServerContext.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/server/ControllerServerContext.java b/blur-core/src/main/java/org/apache/blur/server/ControllerServerContext.java new file mode 100644 index 0000000..9fc3bcd --- /dev/null +++ b/blur-core/src/main/java/org/apache/blur/server/ControllerServerContext.java @@ -0,0 +1,71 @@ +package org.apache.blur.server; + +/** + * 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. + */ +import java.net.SocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.blur.thirdparty.thrift_0_9_0.server.ServerContext; + +/** + * The thrift session that holds the connection string of the client. + */ +public class ControllerServerContext implements ServerContext { + + private final static Map<Thread, ControllerServerContext> _threadsToContext = new ConcurrentHashMap<Thread, ControllerServerContext>(); + private final SocketAddress _localSocketAddress; + private final SocketAddress _remoteSocketAddress; + private final String _connectionString; + + public ControllerServerContext(SocketAddress localSocketAddress, SocketAddress remoteSocketAddress) { + _localSocketAddress = localSocketAddress; + _remoteSocketAddress = remoteSocketAddress; + _connectionString = _localSocketAddress.toString() + "\t" + _remoteSocketAddress.toString(); + } + + /** + * Registers the {@link ControllerServerContext} for this thread. + * + * @param context + * the {@link ControllerServerContext}. + */ + public static void registerContextForCall(ControllerServerContext context) { + _threadsToContext.put(Thread.currentThread(), context); + } + + /** + * Gets the {@link ControllerServerContext} for this {@link Thread}. + * + * @return the {@link ControllerServerContext}. + */ + public static ControllerServerContext getShardServerContext() { + return _threadsToContext.get(Thread.currentThread()); + } + + public SocketAddress getRocalSocketAddress() { + return _localSocketAddress; + } + + public SocketAddress getRemoteSocketAddress() { + return _remoteSocketAddress; + } + + public String getConnectionString() { + return _connectionString; + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/server/ControllerServerEventHandler.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/server/ControllerServerEventHandler.java b/blur-core/src/main/java/org/apache/blur/server/ControllerServerEventHandler.java new file mode 100644 index 0000000..7ca983d --- /dev/null +++ b/blur-core/src/main/java/org/apache/blur/server/ControllerServerEventHandler.java @@ -0,0 +1,92 @@ +package org.apache.blur.server; + +/** + * 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. + */ +import static org.apache.blur.metrics.MetricsConstants.BLUR; +import static org.apache.blur.metrics.MetricsConstants.ORG_APACHE_BLUR; + +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.blur.log.Log; +import org.apache.blur.log.LogFactory; +import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TProtocol; +import org.apache.blur.thirdparty.thrift_0_9_0.server.ServerContext; +import org.apache.blur.thirdparty.thrift_0_9_0.server.TServerEventHandler; +import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport; + +import com.yammer.metrics.Metrics; +import com.yammer.metrics.core.Gauge; +import com.yammer.metrics.core.Meter; +import com.yammer.metrics.core.MetricName; + +/** + * {@link ConrtollerServerContext} is the session manager for the controller servers. + */ +public class ControllerServerEventHandler implements TServerEventHandler { + + private static final Log LOG = LogFactory.getLog(ControllerServerEventHandler.class); + private final Meter _connectionMeter; + private final AtomicLong _connections = new AtomicLong(); + + public ControllerServerEventHandler() { + Metrics.newGauge(new MetricName(ORG_APACHE_BLUR, BLUR, "Connections"), new Gauge<Long>() { + @Override + public Long value() { + return null; + } + }); + _connectionMeter = Metrics.newMeter(new MetricName(ORG_APACHE_BLUR, BLUR, "Connections/s"), "Connections/s", + TimeUnit.SECONDS); + } + + @Override + public void preServe() { + LOG.debug("preServe"); + } + + @Override + public ServerContext createContext(TProtocol input, TProtocol output, Object selectionKeyObject) { + LOG.debug("Client connected"); + SelectionKey selectionKey = (SelectionKey) selectionKeyObject; + SocketChannel channel = (SocketChannel) selectionKey.channel(); + Socket socket = channel.socket(); + SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress(); + SocketAddress localSocketAddress = socket.getLocalSocketAddress(); + _connectionMeter.mark(); + _connections.incrementAndGet(); + return new ControllerServerContext(localSocketAddress, remoteSocketAddress); + } + + @Override + public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output) { + LOG.debug("Client disconnected"); + _connections.decrementAndGet(); + } + + @Override + public void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport) { + LOG.debug("Method called"); + ControllerServerContext context = (ControllerServerContext) serverContext; + ControllerServerContext.registerContextForCall(context); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/server/ShardServerContext.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/server/ShardServerContext.java b/blur-core/src/main/java/org/apache/blur/server/ShardServerContext.java index 431ec96..2b80339 100644 --- a/blur-core/src/main/java/org/apache/blur/server/ShardServerContext.java +++ b/blur-core/src/main/java/org/apache/blur/server/ShardServerContext.java @@ -17,6 +17,7 @@ package org.apache.blur.server; * limitations under the License. */ import java.io.IOException; +import java.net.SocketAddress; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -39,6 +40,15 @@ public class ShardServerContext implements ServerContext { private final static Map<Thread, ShardServerContext> _threadsToContext = new ConcurrentHashMap<Thread, ShardServerContext>(); private final Map<String, IndexSearcherClosable> _indexSearcherMap = new HashMap<String, IndexSearcherClosable>(); + private final SocketAddress _localSocketAddress; + private final SocketAddress _remoteSocketAddress; + private final String _connectionString; + + public ShardServerContext(SocketAddress localSocketAddress, SocketAddress remoteSocketAddress) { + _localSocketAddress = localSocketAddress; + _remoteSocketAddress = remoteSocketAddress; + _connectionString = _localSocketAddress.toString() + "\t" + _remoteSocketAddress.toString(); + } /** * Registers the {@link ShardServerContext} for this thread. @@ -130,4 +140,15 @@ public class ShardServerContext implements ServerContext { return table + "/" + shard; } + public SocketAddress getRocalSocketAddress() { + return _localSocketAddress; + } + + public SocketAddress getRemoteSocketAddress() { + return _remoteSocketAddress; + } + + public String getConnectionString() { + return _connectionString; + } } http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/server/ShardServerEventHandler.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/server/ShardServerEventHandler.java b/blur-core/src/main/java/org/apache/blur/server/ShardServerEventHandler.java index 0f0742a..55fb8d4 100644 --- a/blur-core/src/main/java/org/apache/blur/server/ShardServerEventHandler.java +++ b/blur-core/src/main/java/org/apache/blur/server/ShardServerEventHandler.java @@ -19,6 +19,10 @@ package org.apache.blur.server; import static org.apache.blur.metrics.MetricsConstants.BLUR; import static org.apache.blur.metrics.MetricsConstants.ORG_APACHE_BLUR; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -43,7 +47,7 @@ public class ShardServerEventHandler implements TServerEventHandler { private static final Log LOG = LogFactory.getLog(ShardServerEventHandler.class); private final Meter _connectionMeter; private final AtomicLong _connections = new AtomicLong(); - + public ShardServerEventHandler() { Metrics.newGauge(new MetricName(ORG_APACHE_BLUR, BLUR, "Connections"), new Gauge<Long>() { @Override @@ -51,7 +55,8 @@ public class ShardServerEventHandler implements TServerEventHandler { return null; } }); - _connectionMeter = Metrics.newMeter(new MetricName(ORG_APACHE_BLUR, BLUR, "Connections/s"), "Connections/s", TimeUnit.SECONDS); + _connectionMeter = Metrics.newMeter(new MetricName(ORG_APACHE_BLUR, BLUR, "Connections/s"), "Connections/s", + TimeUnit.SECONDS); } @Override @@ -60,11 +65,16 @@ public class ShardServerEventHandler implements TServerEventHandler { } @Override - public ServerContext createContext(TProtocol input, TProtocol output) { + public ServerContext createContext(TProtocol input, TProtocol output, Object selectionKeyObject) { LOG.debug("Client connected"); + SelectionKey selectionKey = (SelectionKey) selectionKeyObject; + SocketChannel channel = (SocketChannel) selectionKey.channel(); + Socket socket = channel.socket(); + SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress(); + SocketAddress localSocketAddress = socket.getLocalSocketAddress(); _connectionMeter.mark(); _connections.incrementAndGet(); - return new ShardServerContext(); + return new ShardServerContext(localSocketAddress, remoteSocketAddress); } @Override http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurControllerServer.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurControllerServer.java b/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurControllerServer.java index 4fea26e..a67c6bf 100644 --- a/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurControllerServer.java +++ b/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurControllerServer.java @@ -50,6 +50,7 @@ import org.apache.blur.manager.clusterstatus.ZookeeperClusterStatus; import org.apache.blur.manager.indexserver.BlurServerShutDown; import org.apache.blur.manager.indexserver.BlurServerShutDown.BlurShutdown; import org.apache.blur.metrics.ReporterSetup; +import org.apache.blur.server.ControllerServerEventHandler; import org.apache.blur.thrift.generated.Blur.Iface; import org.apache.blur.utils.BlurConstants; import org.apache.blur.utils.BlurUtil; @@ -120,9 +121,11 @@ public class ThriftBlurControllerServer extends ThriftServer { controllerServer.init(); - Iface iface = BlurUtil.recordMethodCallsAndAverageTimes(controllerServer, Iface.class); + Iface iface = BlurUtil.recordMethodCallsAndAverageTimes(controllerServer, Iface.class, true); int threadCount = configuration.getInt(BLUR_CONTROLLER_SERVER_THRIFT_THREAD_COUNT, 32); + + ControllerServerEventHandler eventHandler = new ControllerServerEventHandler(); final ThriftBlurControllerServer server = new ThriftBlurControllerServer(); server.setNodeName(nodeName); @@ -130,6 +133,7 @@ public class ThriftBlurControllerServer extends ThriftServer { server.setBindAddress(bindAddress); server.setBindPort(bindPort); server.setThreadCount(threadCount); + server.setEventHandler(eventHandler); server.setIface(iface); int baseGuiPort = Integer.parseInt(configuration.get(BLUR_GUI_CONTROLLER_PORT)); http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java b/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java index 25f2f0c..d26bdee 100644 --- a/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java +++ b/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java @@ -218,7 +218,7 @@ public class ThriftBlurShardServer extends ThriftServer { shardServer.setConfiguration(configuration); shardServer.init(); - Iface iface = BlurUtil.recordMethodCallsAndAverageTimes(shardServer, Iface.class); + Iface iface = BlurUtil.recordMethodCallsAndAverageTimes(shardServer, Iface.class, false); if (httpServer != null) { WebAppContext context = httpServer.getContext(); context.addServlet(new ServletHolder(new TServlet(new Blur.Processor<Blur.Iface>(iface), http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-core/src/main/java/org/apache/blur/utils/BlurUtil.java ---------------------------------------------------------------------- diff --git a/blur-core/src/main/java/org/apache/blur/utils/BlurUtil.java b/blur-core/src/main/java/org/apache/blur/utils/BlurUtil.java index a26d3db..ee0ac9b 100644 --- a/blur-core/src/main/java/org/apache/blur/utils/BlurUtil.java +++ b/blur-core/src/main/java/org/apache/blur/utils/BlurUtil.java @@ -33,9 +33,11 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -46,6 +48,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLongArray; import java.util.regex.Pattern; @@ -56,6 +59,8 @@ import org.apache.blur.manager.results.BlurResultComparator; import org.apache.blur.manager.results.BlurResultIterable; import org.apache.blur.manager.results.BlurResultPeekableIteratorComparator; import org.apache.blur.manager.results.PeekableIterator; +import org.apache.blur.server.ControllerServerContext; +import org.apache.blur.server.ShardServerContext; import org.apache.blur.thirdparty.thrift_0_9_0.TBase; import org.apache.blur.thirdparty.thrift_0_9_0.TException; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TJSONProtocol; @@ -74,6 +79,7 @@ import org.apache.blur.thrift.generated.Row; import org.apache.blur.thrift.generated.RowMutation; import org.apache.blur.thrift.generated.RowMutationType; import org.apache.blur.thrift.generated.Selector; +import org.apache.blur.thrift.util.ResetableTMemoryBuffer; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; @@ -104,6 +110,9 @@ import com.yammer.metrics.core.MetricName; public class BlurUtil { + private static final Log REQUEST_LOG = LogFactory.getLog("REQUEST_LOG"); + private static final Log RESPONSE_LOG = LogFactory.getLog("RESPONSE_LOG"); + private static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {}; private static final Class<?>[] EMPTY_PARAMETER_TYPES = new Class[] {}; private static final Log LOG = LogFactory.getLog(BlurUtil.class); @@ -113,30 +122,149 @@ public class BlurUtil { public static final Comparator<? super PeekableIterator<BlurResult, BlurException>> HITS_PEEKABLE_ITERATOR_COMPARATOR = new BlurResultPeekableIteratorComparator(); public static final Comparator<? super BlurResult> HITS_COMPARATOR = new BlurResultComparator(); public static final Term PRIME_DOC_TERM = new Term(BlurConstants.PRIME_DOC, BlurConstants.PRIME_DOC_VALUE); + + static class LoggerArgsState { + public LoggerArgsState(int size) { + _buffer = new ResetableTMemoryBuffer(size); + _tjsonProtocol = new TJSONProtocol(_buffer); + } + TJSONProtocol _tjsonProtocol; + ResetableTMemoryBuffer _buffer; + StringBuilder _builder = new StringBuilder(); + } @SuppressWarnings("unchecked") - public static <T extends Iface> T recordMethodCallsAndAverageTimes(final T t, Class<T> clazz) { + public static <T extends Iface> T recordMethodCallsAndAverageTimes(final T t, Class<T> clazz, final boolean controller) { final Map<String, Histogram> histogramMap = new ConcurrentHashMap<String, Histogram>(); Method[] declaredMethods = Iface.class.getDeclaredMethods(); for (Method m : declaredMethods) { String name = m.getName(); histogramMap.put(name, Metrics.newHistogram(new MetricName(ORG_APACHE_BLUR, BLUR, name, THRIFT_CALLS))); } + final String prefix = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); InvocationHandler handler = new InvocationHandler() { + private final AtomicLong _requestCounter = new AtomicLong(); + private ThreadLocal<LoggerArgsState> _loggerArgsState = new ThreadLocal<LoggerArgsState>() { + @Override + protected LoggerArgsState initialValue() { + return new LoggerArgsState(1024); + } + }; + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + long requestNumber = _requestCounter.incrementAndGet(); + String requestId = prefix + "-" + requestNumber; + String connectionString; + if (controller) { + ControllerServerContext controllerServerContext = ControllerServerContext.getShardServerContext(); + connectionString = controllerServerContext.getConnectionString(); + } else { + ShardServerContext shardServerContext = ShardServerContext.getShardServerContext(); + connectionString = shardServerContext.getConnectionString(); + } + String argsStr = null; long start = System.nanoTime(); + String name = method.getName(); + boolean error = false; + LoggerArgsState loggerArgsState = null; try { + if (REQUEST_LOG.isInfoEnabled()) { + if (argsStr == null) { + loggerArgsState = _loggerArgsState.get(); + argsStr = getArgsStr(args, name, loggerArgsState); + } + REQUEST_LOG.info(requestId + "\t" + connectionString + "\t" + name + "\t" + argsStr); + } return method.invoke(t, args); } catch (InvocationTargetException e) { + error = true; throw e.getTargetException(); } finally { long end = System.nanoTime(); - String name = method.getName(); + double ms = (end - start) / 1000000.0; + if (RESPONSE_LOG.isInfoEnabled()) { + if (argsStr == null) { + if (loggerArgsState == null) { + loggerArgsState = _loggerArgsState.get(); + } + argsStr = getArgsStr(args, name, loggerArgsState); + } + if (error) { + RESPONSE_LOG.info(requestId + "\t" + connectionString + "\tERROR\t" + name + "\t" + ms + "\t" + argsStr); + } else { + RESPONSE_LOG + .info(requestId + "\t" + connectionString + "\tSUCCESS\t" + name + "\t" + ms + "\t" + argsStr); + } + } Histogram histogram = histogramMap.get(name); histogram.update((end - start) / 1000); } } + + private String getArgsStr(Object[] args, String name, LoggerArgsState loggerArgsState) { + String argsStr; + if (name.equals("mutate")) { + RowMutation rowMutation = (RowMutation) args[0]; + if (rowMutation == null) { + argsStr = "[null]"; + } else { + argsStr = "[" + rowMutation.getTable() + "," + rowMutation.getRowId() + "]"; + } + } else if (name.equals("mutateBatch")) { + argsStr = "[Batch Update]"; + } else { + argsStr = getArgsStr(args, loggerArgsState); + } + return argsStr; + } + + private String getArgsStr(Object[] args, LoggerArgsState loggerArgsState) { + if (args == null) { + return null; + } + StringBuilder builder = loggerArgsState._builder; + builder.setLength(0); + for (Object o : args) { + if (builder.length() == 0) { + builder.append('['); + } else { + builder.append(','); + } + builder.append(getArgsStr(o, loggerArgsState)); + } + if (builder.length() != 0) { + builder.append(']'); + } + return builder.toString(); + } + + @SuppressWarnings("rawtypes") + private String getArgsStr(Object o, LoggerArgsState loggerArgsState) { + if (o == null) { + return null; + } + if (o instanceof TBase) { + return getArgsStr((TBase) o, loggerArgsState); + } + return o.toString(); + } + + @SuppressWarnings("rawtypes") + private String getArgsStr(TBase o, LoggerArgsState loggerArgsState) { + ResetableTMemoryBuffer buffer = loggerArgsState._buffer; + TJSONProtocol tjsonProtocol = loggerArgsState._tjsonProtocol; + buffer.resetBuffer(); + tjsonProtocol.reset(); + try { + o.write(tjsonProtocol); + } catch (TException e) { + LOG.error("Unknown error tyring to write object [{0}] to json.", e, o); + } + byte[] array = buffer.getArray(); + int length = buffer.length(); + return new String(array, 0, length); + } }; return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, handler); } @@ -673,10 +801,11 @@ public class BlurUtil { public static String getPid() { return ManagementFactory.getRuntimeMXBean().getName(); } - -// public static <T> BlurIterator<T, BlurException> convert(final Iterator<T> iterator) { -// return convert(iterator, BlurException.class); -// } + + // public static <T> BlurIterator<T, BlurException> convert(final Iterator<T> + // iterator) { + // return convert(iterator, BlurException.class); + // } public static <T, E extends Exception> BlurIterator<T, E> convert(final Iterator<T> iterator) { return new BlurIterator<T, E>() { http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TServerEventHandler.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TServerEventHandler.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TServerEventHandler.java index d0ebfe7..d617e64 100644 --- a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TServerEventHandler.java +++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TServerEventHandler.java @@ -38,9 +38,10 @@ public interface TServerEventHandler { /** * Called when a new client has connected and is about to being processing. + * @param frameBuffer */ ServerContext createContext(TProtocol input, - TProtocol output); + TProtocol output, Object frameBuffer); /** * Called when a client has finished request-handling to delete server http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TSimpleServer.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TSimpleServer.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TSimpleServer.java index bad4a60..e75518b 100644 --- a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TSimpleServer.java +++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TSimpleServer.java @@ -74,7 +74,7 @@ public class TSimpleServer extends TServer { inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); if (eventHandler_ != null) { - connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol); + connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol, null); } while (true) { if (eventHandler_ != null) { http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TThreadPoolServer.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TThreadPoolServer.java b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TThreadPoolServer.java index fc744f1..07cd950 100644 --- a/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TThreadPoolServer.java +++ b/blur-thrift/src/main/java/org/apache/blur/thirdparty/thrift_0_9_0/server/TThreadPoolServer.java @@ -193,7 +193,7 @@ public class TThreadPoolServer extends TServer { eventHandler = getEventHandler(); if (eventHandler != null) { - connectionContext = eventHandler.createContext(inputProtocol, outputProtocol); + connectionContext = eventHandler.createContext(inputProtocol, outputProtocol, null); } // we check stopped_ first to make sure we're not supposed to be shutting // down. this is necessary for graceful shutdown. http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thrift/server/AbstractNonblockingServer.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thrift/server/AbstractNonblockingServer.java b/blur-thrift/src/main/java/org/apache/blur/thrift/server/AbstractNonblockingServer.java index 5f8708f..5fee759 100644 --- a/blur-thrift/src/main/java/org/apache/blur/thrift/server/AbstractNonblockingServer.java +++ b/blur-thrift/src/main/java/org/apache/blur/thrift/server/AbstractNonblockingServer.java @@ -318,7 +318,7 @@ public abstract class AbstractNonblockingServer extends TServer { outProt_ = outputProtocolFactory_.getProtocol(outTrans_); if (eventHandler_ != null) { - context_ = eventHandler_.createContext(inProt_, outProt_); + context_ = eventHandler_.createContext(inProt_, outProt_, selectionKey); } else { context_ = null; } http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTByteArrayOutputStream.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTByteArrayOutputStream.java b/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTByteArrayOutputStream.java new file mode 100644 index 0000000..990d8f0 --- /dev/null +++ b/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTByteArrayOutputStream.java @@ -0,0 +1,50 @@ +/* + * 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.blur.thrift.util; + +import org.apache.blur.thirdparty.thrift_0_9_0.TByteArrayOutputStream; + +/** + * Class that allows access to the underlying buf without doing deep copies on + * it. + * + */ +public class ResetableTByteArrayOutputStream extends TByteArrayOutputStream { + public ResetableTByteArrayOutputStream(int size) { + super(size); + } + + public ResetableTByteArrayOutputStream() { + super(); + } + + public byte[] get() { + return buf; + } + + public int len() { + return count; + } + + public void resetBuffer() { + count = 0; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTMemoryBuffer.java ---------------------------------------------------------------------- diff --git a/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTMemoryBuffer.java b/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTMemoryBuffer.java new file mode 100644 index 0000000..b28409e --- /dev/null +++ b/blur-thrift/src/main/java/org/apache/blur/thrift/util/ResetableTMemoryBuffer.java @@ -0,0 +1,109 @@ +/* + * 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.blur.thrift.util; + +import java.io.UnsupportedEncodingException; + +import org.apache.blur.thirdparty.thrift_0_9_0.TByteArrayOutputStream; +import org.apache.blur.thirdparty.thrift_0_9_0.transport.TTransport; + +/** + * Memory buffer-based implementation of the TTransport interface. + */ +public class ResetableTMemoryBuffer extends TTransport { + /** + * Create a TMemoryBuffer with an initial buffer size of <i>size</i>. The + * internal buffer will grow as necessary to accommodate the size of the data + * being written to it. + */ + public ResetableTMemoryBuffer(int size) { + arr_ = new ResetableTByteArrayOutputStream(size); + } + + @Override + public boolean isOpen() { + return true; + } + + @Override + public void open() { + /* Do nothing */ + } + + @Override + public void close() { + /* Do nothing */ + } + + @Override + public int read(byte[] buf, int off, int len) { + byte[] src = arr_.get(); + int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len); + if (amtToRead > 0) { + System.arraycopy(src, pos_, buf, off, amtToRead); + pos_ += amtToRead; + } + return amtToRead; + } + + @Override + public void write(byte[] buf, int off, int len) { + arr_.write(buf, off, len); + } + + /** + * Output the contents of the memory buffer as a String, using the supplied + * encoding + * + * @param enc + * the encoding to use + * @return the contents of the memory buffer as a String + */ + public String toString(String enc) throws UnsupportedEncodingException { + return arr_.toString(enc); + } + + public String inspect() { + String buf = ""; + byte[] bytes = arr_.toByteArray(); + for (int i = 0; i < bytes.length; i++) { + buf += (pos_ == i ? "==>" : "") + Integer.toHexString(bytes[i] & 0xff) + " "; + } + return buf; + } + + // The contents of the buffer + private TByteArrayOutputStream arr_; + + // Position to read next byte from + private int pos_; + + public int length() { + return arr_.size(); + } + + public byte[] getArray() { + return arr_.get(); + } + + public void resetBuffer() { + ((ResetableTByteArrayOutputStream) arr_).resetBuffer(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a455ee70/distribution/src/main/scripts/conf/log4j.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/scripts/conf/log4j.xml b/distribution/src/main/scripts/conf/log4j.xml index 518413a..787fc13 100644 --- a/distribution/src/main/scripts/conf/log4j.xml +++ b/distribution/src/main/scripts/conf/log4j.xml @@ -21,10 +21,9 @@ under the License. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> - <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%-5p %d{yyyyMMdd_HH:mm:ss:sss_z} [%t] %c{2}: %m%n" /> + <param name="ConversionPattern" value="%-5p %d{yyyyMMdd_HH:mm:ss:SSS_z} [%t] %c{2}: %m%n" /> </layout> </appender> @@ -37,7 +36,33 @@ under the License. <param name="DatePattern" value="'.'yyyyMMdd" /> <param name="Append" value="true" /> <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%-5p %d{yyyyMMdd_HH:mm:ss:sss_z} [%t] %c{2}: %m%n" /> + <param name="ConversionPattern" value="%-5p %d{yyyyMMdd_HH:mm:ss:SSS_z} [%t] %c{2}: %m%n" /> + </layout> + </appender> + + <appender name="ASYNC_REQUEST_LOG_FILE" class="org.apache.log4j.AsyncAppender"> + <appender-ref ref="REQUEST_LOG_FILE" /> + </appender> + + <appender name="REQUEST_LOG_FILE" class="org.apache.log4j.DailyRollingFileAppender"> + <param name="File" value="${blur.logs.dir}/request_${blur.name}.log" /> + <param name="DatePattern" value="'.'yyyyMMdd" /> + <param name="Append" value="true" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{yyyyMMdd_HH:mm:ss:SSS_z}\t%m\t%t%n" /> + </layout> + </appender> + + <appender name="ASYNC_RESPONSE_LOG_FILE" class="org.apache.log4j.AsyncAppender"> + <appender-ref ref="RESPONSE_LOG_FILE" /> + </appender> + + <appender name="RESPONSE_LOG_FILE" class="org.apache.log4j.DailyRollingFileAppender"> + <param name="File" value="${blur.logs.dir}/response_${blur.name}.log" /> + <param name="DatePattern" value="'.'yyyyMMdd" /> + <param name="Append" value="true" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{yyyyMMdd_HH:mm:ss:SSS_z}\t%m\t%t%n" /> </layout> </appender> @@ -45,6 +70,18 @@ under the License. <level value="ERROR" /> <appender-ref ref="ASYNC"/> </logger> + + <logger name="REQUEST_LOG" additivity="false"> + <!-- Make value = "INFO"to enable --> + <level value="ERROR" /> + <appender-ref ref="ASYNC_REQUEST_LOG_FILE"/> + </logger> + + <logger name="RESPONSE_LOG" additivity="false"> + <!-- Make value = "INFO"to enable --> + <level value="ERROR" /> + <appender-ref ref="ASYNC_RESPONSE_LOG_FILE"/> + </logger> <!--root> For production use, the async configuration will be better for performance at the cost of not seeing the final flushed log events.
