diff --git a/client/client.go b/client/client.go
index 24eeb0338629fdbaae0aa28367a074e436e1d415..34275c8b2deacc6a10d18d18a496297dd3b44430 100644
--- a/client/client.go
+++ b/client/client.go
@@ -80,7 +80,7 @@ func NewErisNodeClient(rpcString string) *ErisNodeClient {
 // it needs to be initialised before go-rpc, hence it's placement here.
 func init() {
 	h := tendermint_log.LvlFilterHandler(tendermint_log.LvlWarn, tendermint_log.StdoutHandler)
-    tendermint_log.Root().SetHandler(h)
+	tendermint_log.Root().SetHandler(h)
 }
 
 //------------------------------------------------------------------------------------
diff --git a/cmd/serve.go b/cmd/serve.go
index 8d23e4b3b585108040e78671be510d281d2d60f3..f8b99c08c4fa3ee178b7c967af063ba89fe8aa05 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -115,6 +115,8 @@ func NewCoreFromDo(do *definitions.Do) (*core.Core, error) {
 	// Capture all logging from tendermint/tendermint and tendermint/go-*
 	// dependencies
 	lifecycle.CaptureTendermintLog15Output(logger)
+	// And from stdlib go log
+	lifecycle.CaptureStdlibLogOutput(logger)
 
 	cmdLogger := logger.With("command", "serve")
 
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 03296eed028a0151a8a5ae3d696d58107caa96c9..01fc2d12761e56399c2c543359f4c26905ff4d4a 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -28,7 +28,8 @@ func LoadConsensusEngineInPipe(moduleConfig *config.ModuleConfig,
 	pipe definitions.Pipe) error {
 	switch moduleConfig.Name {
 	case "tendermint":
-		tmint, err := tendermint.NewTendermint(moduleConfig, pipe.GetApplication())
+		tmint, err := tendermint.NewTendermint(moduleConfig, pipe.GetApplication(),
+		pipe.Logger().With())
 		if err != nil {
 			return fmt.Errorf("Failed to load Tendermint node: %v", err)
 		}
diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go
index 87553697880fcd144c14c0bf70ff3eab3cdcf0c2..545e4c1acb46200f3e5e24d3f0b58bc273dc151a 100644
--- a/consensus/tendermint/tendermint.go
+++ b/consensus/tendermint/tendermint.go
@@ -41,6 +41,7 @@ import (
 	// files  "github.com/eris-ltd/eris-db/files"
 	blockchain_types "github.com/eris-ltd/eris-db/blockchain/types"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	"github.com/eris-ltd/eris-db/txs"
 	"github.com/tendermint/go-wire"
 )
@@ -57,7 +58,8 @@ var _ consensus_types.ConsensusEngine = (*Tendermint)(nil)
 var _ blockchain_types.Blockchain = (*Tendermint)(nil)
 
 func NewTendermint(moduleConfig *config.ModuleConfig,
-	application manager_types.Application) (*Tendermint, error) {
+	application manager_types.Application,
+	logger loggers.InfoTraceLogger) (*Tendermint, error) {
 	// re-assert proper configuration for module
 	if moduleConfig.Version != GetTendermintVersion().GetMinorVersionString() {
 		return nil, fmt.Errorf("Version string %s did not match %s",
@@ -74,7 +76,7 @@ func NewTendermint(moduleConfig *config.ModuleConfig,
 	tendermintConfigViper, err := config.ViperSubConfig(moduleConfig.Config, "configuration")
 	if tendermintConfigViper == nil {
 		return nil,
-				fmt.Errorf("Failed to extract Tendermint configuration subtree: %s", err)
+			fmt.Errorf("Failed to extract Tendermint configuration subtree: %s", err)
 	}
 	// wrap a copy of the viper config in a tendermint/go-config interface
 	tmintConfig := GetTendermintConfig(tendermintConfigViper)
diff --git a/core/core.go b/core/core.go
index c4e08963023b7de5ba4611a35ccf134dd378414d..3bd32fdcde0c8ec909ab244c06a1479c2447caae 100644
--- a/core/core.go
+++ b/core/core.go
@@ -22,20 +22,19 @@ import (
 	// TODO: [ben] swap out go-events with eris-db/event (currently unused)
 	events "github.com/tendermint/go-events"
 
-	log "github.com/eris-ltd/eris-logger"
-
-	config "github.com/eris-ltd/eris-db/config"
-	consensus "github.com/eris-ltd/eris-db/consensus"
-	definitions "github.com/eris-ltd/eris-db/definitions"
-	event "github.com/eris-ltd/eris-db/event"
-	manager "github.com/eris-ltd/eris-db/manager"
+	"github.com/eris-ltd/eris-db/config"
+	"github.com/eris-ltd/eris-db/consensus"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/event"
+	"github.com/eris-ltd/eris-db/manager"
 	// rpc_v0 is carried over from Eris-DBv0.11 and before on port 1337
 	rpc_v0 "github.com/eris-ltd/eris-db/rpc/v0"
 	// rpc_tendermint is carried over from Eris-DBv0.11 and before on port 46657
 
+	"github.com/eris-ltd/eris-db/logging"
 	"github.com/eris-ltd/eris-db/logging/loggers"
 	rpc_tendermint "github.com/eris-ltd/eris-db/rpc/tendermint/core"
-	server "github.com/eris-ltd/eris-db/server"
+	"github.com/eris-ltd/eris-db/server"
 )
 
 // Core is the high-level structure
@@ -60,15 +59,15 @@ func NewCore(chainId string,
 	if err != nil {
 		return nil, fmt.Errorf("Failed to load application pipe: %v", err)
 	}
-	log.Debug("Loaded pipe with application manager")
+	logging.TraceMsg(logger, "Loaded pipe with application manager")
 	// pass the consensus engine into the pipe
 	if e := consensus.LoadConsensusEngineInPipe(consensusConfig, pipe); e != nil {
 		return nil, fmt.Errorf("Failed to load consensus engine in pipe: %v", e)
 	}
 	tendermintPipe, err := pipe.GetTendermintPipe()
 	if err != nil {
-		log.Warn(fmt.Sprintf("Tendermint gateway not supported by %s",
-			managerConfig.Version))
+		logging.TraceMsg(logger, "Tendermint gateway not supported by manager",
+			"manager-version", managerConfig.Version)
 	}
 	return &Core{
 		chainId:        chainId,
diff --git a/glide.lock b/glide.lock
index cfd0d6066dea987150500aa66f1a88ff75ad7e73..34cea95404a3b7a0d4ff200facba76ad4cd14890 100644
--- a/glide.lock
+++ b/glide.lock
@@ -233,4 +233,6 @@ imports:
   - term
 - name: github.com/eris-ltd/eris-logger
   version: ea48a395d6ecc0eccc67a26da9fc7a6106fabb84
+- name: github.com/streadway/simpleuuid
+  version: 6617b501e485b77e61b98cd533aefff9e258b5a7
 devImports: []
diff --git a/glide.yaml b/glide.yaml
index 7b6f0398c08f09f4ba7de4b54177d805a4a48583..9ad7b4d4edc758ee21952e15cf611acc9d47fc12 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -29,3 +29,4 @@ import:
 - package: github.com/inconshreveable/log15
 - package: github.com/Sirupsen/logrus
   version: ^0.11.0
+- package: github.com/streadway/simpleuuid
diff --git a/logging/adapters/tendermint_log15/convert.go b/logging/adapters/tendermint_log15/convert.go
index 52cda465988566abeda50ac6ab28fad5c8a90838..f7be8420866a67a987afb39f84b2e93cea849018 100644
--- a/logging/adapters/tendermint_log15/convert.go
+++ b/logging/adapters/tendermint_log15/convert.go
@@ -27,7 +27,7 @@ func LogLineToRecord(keyvals ...interface{}) *log15.Record {
 		Lvl:  Log15LvlFromString(level),
 		Msg:  message,
 		Call: call,
-		Ctx:  append(ctx, structure.CallerKey, call),
+		Ctx:  ctx,
 		KeyNames: log15.RecordKeyNames{
 			Time: structure.TimeKey,
 			Msg:  structure.MessageKey,
diff --git a/logging/convention.go b/logging/convention.go
new file mode 100644
index 0000000000000000000000000000000000000000..3c75270ac36e65e35f7cc9af14080e282ac873da
--- /dev/null
+++ b/logging/convention.go
@@ -0,0 +1,49 @@
+package logging
+
+import (
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
+	"github.com/eris-ltd/eris-db/util/slice"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// Helper functions for InfoTraceLoggers, sort of extension methods to loggers
+// to centralise and establish logging conventions on top of in with the base
+// logging interface
+
+// Record structured Info log line with a message and conventional keys
+func InfoMsgVals(logger loggers.InfoTraceLogger, message string, vals ...interface{}) {
+	MsgVals(kitlog.LoggerFunc(logger.Info), message, vals...)
+}
+
+// Record structured Trace log line with a message and conventional keys
+func TraceMsgVals(logger loggers.InfoTraceLogger, message string, vals ...interface{}) {
+	MsgVals(kitlog.LoggerFunc(logger.Trace), message, vals...)
+}
+
+// Record structured Info log line with a message
+func InfoMsg(logger loggers.InfoTraceLogger, message string, keyvals ...interface{}) {
+	Msg(kitlog.LoggerFunc(logger.Info), message, keyvals...)
+}
+
+// Record structured Trace log line with a message
+func TraceMsg(logger loggers.InfoTraceLogger, message string, keyvals ...interface{}) {
+	Msg(kitlog.LoggerFunc(logger.Trace), message, keyvals...)
+}
+
+// Record a structured log line with a message
+func Msg(logger kitlog.Logger, message string, keyvals ...interface{}) error {
+	prepended := slice.CopyPrepend(keyvals, structure.MessageKey, message)
+	return logger.Log(prepended...)
+}
+
+// Record a structured log line with a message and conventional keys
+func MsgVals(logger kitlog.Logger, message string, vals ...interface{}) error {
+	keyvals := make([]interface{}, len(vals)*2)
+	for i := 0; i < len(vals); i++ {
+		kv := i * 2
+		keyvals[kv] = structure.KeyFromValue(vals[i])
+		keyvals[kv+1] = vals[i]
+	}
+	return Msg(logger, message, keyvals)
+}
diff --git a/logging/lifecycle/lifecycle.go b/logging/lifecycle/lifecycle.go
index fd85a3248a1d5329d66077b4b8d8720d8d7a242a..4468e54b4baf2f319cf9ff77481400f35357dece 100644
--- a/logging/lifecycle/lifecycle.go
+++ b/logging/lifecycle/lifecycle.go
@@ -6,11 +6,14 @@ import (
 	"os"
 
 	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/adapters/stdlib"
 	tmLog15adapter "github.com/eris-ltd/eris-db/logging/adapters/tendermint_log15"
 	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
 	kitlog "github.com/go-kit/kit/log"
 	tmLog15 "github.com/tendermint/log15"
-	"github.com/eris-ltd/eris-db/logging/structure"
+	"github.com/streadway/simpleuuid"
+	"time"
 )
 
 func NewLoggerFromConfig(LoggingConfig logging.LoggingConfig) loggers.InfoTraceLogger {
@@ -27,11 +30,22 @@ func NewStdErrLogger() loggers.InfoTraceLogger {
 
 func NewLogger(infoLogger, traceLogger kitlog.Logger) loggers.InfoTraceLogger {
 	infoTraceLogger := loggers.NewInfoTraceLogger(infoLogger, traceLogger)
-	return logging.WithMetadata(infoTraceLogger)
+	// Create a random ID based on start time
+	uuid, _ := simpleuuid.NewTime(time.Now())
+	var runId string
+	if uuid != nil {
+		runId = uuid.String()
+	}
+	return logging.WithMetadata(infoTraceLogger.With(structure.RunId, runId))
 }
 
 func CaptureTendermintLog15Output(infoTraceLogger loggers.InfoTraceLogger) {
 	tmLog15.Root().SetHandler(
 		tmLog15adapter.InfoTraceLoggerAsLog15Handler(infoTraceLogger.
-			With(structure.ComponentKey, "tendermint")))
+			With(structure.ComponentKey, "tendermint_log15")))
+}
+
+func CaptureStdlibLogOutput(infoTraceLogger loggers.InfoTraceLogger) {
+	stdlib.CaptureRootLogger(infoTraceLogger.
+		With(structure.ComponentKey, "stdlib_log"))
 }
diff --git a/logging/loggers/info_trace_logger.go b/logging/loggers/info_trace_logger.go
index 7374477a92a40a80a8d726bf4da136f203e645af..6cbdcee6bd9f0aeb2d7965465835f304226eb42a 100644
--- a/logging/loggers/info_trace_logger.go
+++ b/logging/loggers/info_trace_logger.go
@@ -33,7 +33,7 @@ type InfoTraceLogger interface {
 	// understand or debug the system. Any handled errors or warnings should be
 	// sent to the Info channel (where you may wish to tag them with a suitable
 	// key-value pair to categorise them as such).
-	Info(keyvals ...interface{})
+	Info(keyvals ...interface{}) error
 
 	// Send an log message to the Trace channel, formed of a sequence of key-value
 	// pairs. Trace messages can be used for any state change in the system that
@@ -41,7 +41,7 @@ type InfoTraceLogger interface {
 	// the system or trying to understand the system in detail. If the messages
 	// are very point-like and contain little structure, consider using a metric
 	// instead.
-	Trace(keyvals ...interface{})
+	Trace(keyvals ...interface{}) error
 
 	// A logging context (see go-kit log's Context). Takes a sequence key values
 	// via With or WithPrefix and ensures future calls to log will have those
@@ -66,15 +66,16 @@ var _ InfoTraceLogger = (*infoTraceLogger)(nil)
 var _ kitlog.Logger = (InfoTraceLogger)(nil)
 
 func NewInfoTraceLogger(infoLogger, traceLogger kitlog.Logger) InfoTraceLogger {
-	// We will never halt progress a log emitter. If log output takes too long
-	// will start dropping log lines by using a ring buffer.
+	// We will never halt the progress of a log emitter. If log output takes too
+	// long will start dropping log lines by using a ring buffer.
 	// We also guard against any concurrency bugs in underlying loggers by feeding
 	// them from a single channel
-	logger := kitlog.NewContext(NonBlockingLogger(MultipleChannelLogger(
-		map[string]kitlog.Logger{
-			InfoChannelName:  infoLogger,
-			TraceChannelName: traceLogger,
-		})))
+	logger := kitlog.NewContext(NonBlockingLogger(VectorValuedLogger(
+		MultipleChannelLogger(
+			map[string]kitlog.Logger{
+				InfoChannelName:  infoLogger,
+				TraceChannelName: traceLogger,
+			}))))
 	return &infoTraceLogger{
 		infoLogger: logger.With(
 			structure.ChannelKey, InfoChannelName,
@@ -106,13 +107,13 @@ func (l *infoTraceLogger) WithPrefix(keyvals ...interface{}) InfoTraceLogger {
 	}
 }
 
-func (l *infoTraceLogger) Info(keyvals ...interface{}) {
+func (l *infoTraceLogger) Info(keyvals ...interface{}) error {
 	// We send Info and Trace log lines down the same pipe to keep them ordered
-	l.infoLogger.Log(keyvals...)
+	return l.infoLogger.Log(keyvals...)
 }
 
-func (l *infoTraceLogger) Trace(keyvals ...interface{}) {
-	l.traceLogger.Log(keyvals...)
+func (l *infoTraceLogger) Trace(keyvals ...interface{}) error {
+	return l.traceLogger.Log(keyvals...)
 }
 
 // If logged to as a plain kitlog logger presume the message is for Trace
diff --git a/logging/loggers/vector_valued_logger.go b/logging/loggers/vector_valued_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..b8963db13f61a9e02fdf5273010d9f4910d51009
--- /dev/null
+++ b/logging/loggers/vector_valued_logger.go
@@ -0,0 +1,21 @@
+package loggers
+
+import (
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// Treat duplicate key-values as consecutive entries in a vector-valued lookup
+type vectorValuedLogger struct {
+	logger kitlog.Logger
+}
+
+var _ kitlog.Logger = &vectorValuedLogger{}
+
+func (vvl *vectorValuedLogger) Log(keyvals ...interface{}) error {
+	return vvl.logger.Log(structure.Vectorise(keyvals)...)
+}
+
+func VectorValuedLogger(logger kitlog.Logger) *vectorValuedLogger {
+	return &vectorValuedLogger{logger: logger}
+}
diff --git a/logging/loggers/vector_valued_logger_test.go b/logging/loggers/vector_valued_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d6bc54ebdcfb76d0a7b3f20606828d458e6a5d13
--- /dev/null
+++ b/logging/loggers/vector_valued_logger_test.go
@@ -0,0 +1,17 @@
+package loggers
+
+import (
+	"testing"
+
+	. "github.com/eris-ltd/eris-db/util/slice"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestVectorValuedLogger(t *testing.T) {
+	logger := newTestLogger()
+	vvl := VectorValuedLogger(logger)
+	vvl.Log("foo", "bar", "seen", 1, "seen", 3, "seen", 2)
+
+	assert.Equal(t, Slice("foo", "bar", "seen", Slice(1, 3, 2)),
+		logger.logLines[0])
+}
diff --git a/logging/metadata.go b/logging/metadata.go
index 3fbed2cf4c819a5e28c0788515a3920f45b209ee..d645699902e9a6b9a334390a8824c774aac5a4e6 100644
--- a/logging/metadata.go
+++ b/logging/metadata.go
@@ -6,6 +6,7 @@ import (
 	"github.com/eris-ltd/eris-db/logging/loggers"
 	"github.com/eris-ltd/eris-db/logging/structure"
 	kitlog "github.com/go-kit/kit/log"
+	"github.com/go-stack/stack"
 )
 
 const (
@@ -23,5 +24,10 @@ var defaultTimestampUTCValuer kitlog.Valuer = func() interface{} {
 
 func WithMetadata(infoTraceLogger loggers.InfoTraceLogger) loggers.InfoTraceLogger {
 	return infoTraceLogger.With(structure.TimeKey, defaultTimestampUTCValuer,
-		structure.CallerKey, kitlog.Caller(infoTraceLoggerCallDepth))
+		structure.CallerKey, kitlog.Caller(infoTraceLoggerCallDepth),
+		"trace", TraceValuer())
+}
+
+func TraceValuer() kitlog.Valuer {
+	return func() interface{} { return stack.Trace() }
 }
diff --git a/logging/structure/structure.go b/logging/structure/structure.go
index 9420b20095b4fabab87ce707f082d17968f90ba3..976332be645eb9ea02442819d80f9c250f7001b2 100644
--- a/logging/structure/structure.go
+++ b/logging/structure/structure.go
@@ -1,20 +1,29 @@
 package structure
 
-import . "github.com/eris-ltd/eris-db/util/slice"
+import (
+	"reflect"
+
+	. "github.com/eris-ltd/eris-db/util/slice"
+)
 
 const (
-	// Key for go time.Time object
+	// Log time (time.Time)
 	TimeKey = "time"
-	// Key for call site for log invocation
+	// Call site for log invocation (go-stack.Call)
 	CallerKey = "caller"
-	// Key for String name for level
-	LevelKey   = "level"
-	// Key to switch on for channel in a multiple channel logging context
+	// Level name (string)
+	LevelKey = "level"
+	// Channel name in a vector channel logging context
 	ChannelKey = "channel"
-	// Key for string message
+	// Log message (string)
 	MessageKey = "message"
-	// Key for module or function or struct that is the subject of the logging
+	// Top-level component (choose one) name
 	ComponentKey = "component"
+	// Vector-valued scope
+	ScopeKey = "scope"
+	// Globally unique identifier persisting while a single instance (root process)
+	// of this program/service is running
+	RunId = "run_id"
 )
 
 // Pull the specified values from a structured log line into a map.
@@ -49,6 +58,56 @@ func ValuesAndContext(keyvals []interface{},
 	return vals, context
 }
 
+// Stateful index that tracks the location of a possible vector value
+type vectorValueindex struct {
+	// Location of the value belonging to a key in output slice
+	valueIndex int
+	// Whether or not the value is currently a vector
+	vector     bool
+}
+
+// 'Vectorises' values associated with repeated string keys member by collapsing many values into a single vector value.
+// The result is a copy of keyvals where the first occurrence of each matching key and its first value are replaced by
+// that key and all of its values in a single slice.
+func Vectorise(keyvals []interface{}, vectorKeys ...string) []interface{} {
+	outputKeyvals := make([]interface{}, 0, len(keyvals))
+	// Track the location and vector status of the values in the output
+	valueIndices := make(map[string]*vectorValueindex, len(vectorKeys))
+	elided := 0
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		key := keyvals[i]
+		val := keyvals[i+1]
+
+		// Only attempt to vectorise string keys
+		if k, ok := key.(string); ok {
+			if valueIndices[k] == nil {
+				// Record that this key has been seen once
+				valueIndices[k] = &vectorValueindex{
+					valueIndex: i + 1 - elided,
+				}
+				// Copy the key-value to output with the single value
+				outputKeyvals = append(outputKeyvals, key, val)
+			} else {
+				// We have seen this key before
+				vi := valueIndices[k]
+				if !vi.vector {
+					// This must be the only second occurrence of the key so now vectorise the value
+					outputKeyvals[vi.valueIndex] = []interface{}{outputKeyvals[vi.valueIndex]}
+					vi.vector = true
+				}
+				// Grow the vector value
+				outputKeyvals[vi.valueIndex] = append(outputKeyvals[vi.valueIndex].([]interface{}), val)
+				// We are now running two more elements behind the input keyvals because we have absorbed this key-value pair
+				elided += 2
+			}
+		} else {
+			// Just copy the key-value to the output for non-string keys
+			outputKeyvals = append(outputKeyvals, key, val)
+		}
+	}
+	return outputKeyvals
+}
+
 // Return a single value corresponding to key in keyvals
 func Value(keyvals []interface{}, key interface{}) interface{} {
 	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
@@ -57,4 +116,16 @@ func Value(keyvals []interface{}, key interface{}) interface{} {
 		}
 	}
 	return nil
-}
\ No newline at end of file
+}
+
+// Obtain a canonical key from a value. Useful for structured logging where the
+// type of value alone may be sufficient to determine its key. Providing this
+// function centralises any convention over type names
+func KeyFromValue(val interface{}) string {
+	switch val.(type) {
+	case string:
+		return "text"
+	default:
+		return reflect.TypeOf(val).Name()
+	}
+}
diff --git a/logging/structure/structure_test.go b/logging/structure/structure_test.go
index 2fbdaa3e5e1c525c5ccf836b430ad13ebbb5333a..fde15ff4ae247a02166d91fe7850328c01417e33 100644
--- a/logging/structure/structure_test.go
+++ b/logging/structure/structure_test.go
@@ -13,3 +13,24 @@ func TestValuesAndContext(t *testing.T) {
 	assert.Equal(t, map[interface{}]interface{}{"hello": 1, "fish": 3}, vals)
 	assert.Equal(t, Slice("dog", 2, "fork", 5), ctx)
 }
+
+func TestVectorise(t *testing.T) {
+	kvs := Slice(
+		"scope", "lawnmower",
+		"hub", "budub",
+		"occupation", "fish brewer",
+		"scope", "hose pipe",
+		"flub", "dub",
+		"scope", "rake",
+		"flub", "brub",
+	)
+
+	kvsVector := Vectorise(kvs, "occupation", "scope")
+	assert.Equal(t, Slice(
+		"scope", Slice("lawnmower", "hose pipe", "rake"),
+		"hub", "budub",
+		"occupation", "fish brewer",
+		"flub", Slice("dub", "brub"),
+	),
+		kvsVector)
+}
diff --git a/rpc/tendermint/test/common.go b/rpc/tendermint/test/common.go
index 76909182df98801eab3e08db5b5c4bbfd03617cf..a060833c5091b00156e855c70a276753115d925f 100644
--- a/rpc/tendermint/test/common.go
+++ b/rpc/tendermint/test/common.go
@@ -6,6 +6,7 @@ package test
 import (
 	"fmt"
 
+	vm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core"
 	"github.com/eris-ltd/eris-db/test/fixtures"
 )
@@ -17,6 +18,7 @@ func TestWrapper(runner func() int) int {
 
 	defer ffs.RemoveAll()
 
+	vm.SetDebug(true)
 	err := initGlobalVariables(ffs)
 
 	if err != nil {
diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go
index 8ddce9b340f3aa507ccbffe1fe736408e41cb6b3..8c01b6a2f024d402cbea6dc1e7cea5f54dbf7f7e 100644
--- a/rpc/tendermint/test/shared.go
+++ b/rpc/tendermint/test/shared.go
@@ -88,6 +88,8 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error {
 	// To spill tendermint logs on the floor:
 	// lifecycle.CaptureTendermintLog15Output(loggers.NewNoopInfoTraceLogger())
 	lifecycle.CaptureTendermintLog15Output(logger)
+	lifecycle.CaptureStdlibLogOutput(logger)
+
 	testCore, err = core.NewCore("testCore", consensusConfig, managerConfig,
 		logger)
 	if err != nil {
diff --git a/util/slice/slice.go b/util/slice/slice.go
index 55332d87f5c96aa753f6f0580b306f77385a5134..2c51efd21f89c3478a185d623e54dcc9d4ea3064 100644
--- a/util/slice/slice.go
+++ b/util/slice/slice.go
@@ -58,7 +58,34 @@ func Delete(slice []interface{}, i int, n int) []interface{} {
 	return append(slice[:i], slice[i+n:]...)
 }
 
-//
+// Delete an element at a specific index and return the contracted list
 func DeleteAt(slice []interface{}, i int) []interface{} {
 	return Delete(slice, i, 1)
 }
+
+// Flatten a slice by a list by splicing any elements of the list that are
+// themselves lists into the slice elements to the list in place of slice itself
+func Flatten(slice []interface{}) []interface{} {
+	return DeepFlatten(slice, 1)
+}
+
+// Recursively flattens a list by splicing any sub-lists into their parent until
+// depth is reached. If a negative number is passed for depth then it continues
+// until no elements of the returned list are lists
+func DeepFlatten(slice []interface{}, depth int) []interface{} {
+	if depth == 0 {
+		return slice
+	}
+	returnSlice := []interface{}{}
+
+	for _, element := range slice {
+		if s, ok := element.([]interface{}); ok {
+			returnSlice = append(returnSlice, DeepFlatten(s, depth-1)...)
+		} else {
+			returnSlice = append(returnSlice, element)
+		}
+
+	}
+
+	return returnSlice
+}
diff --git a/util/slice/slice_test.go b/util/slice/slice_test.go
index 4a1f53e71ad0f5c4518e73c1d7b2eaa34ef8abc8..b3d1c9b6a530b1fe050427b3ba41ae8f9f23c388 100644
--- a/util/slice/slice_test.go
+++ b/util/slice/slice_test.go
@@ -23,14 +23,21 @@ func TestCopyPrepend(t *testing.T) {
 }
 
 func TestConcat(t *testing.T) {
-	assert.Equal(t, Slice(1,2,3,4,5), Concat(Slice(1,2,3,4,5)))
-	assert.Equal(t, Slice(1,2,3,4,5), Concat(Slice(1,2,3),Slice(4,5)))
-	assert.Equal(t, Slice(1,2,3,4,5), Concat(Slice(1),Slice(2,3),Slice(4,5)))
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1, 2, 3, 4, 5)))
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1, 2, 3), Slice(4, 5)))
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1), Slice(2, 3), Slice(4, 5)))
 	assert.Equal(t, EmptySlice(), Concat(nil))
 	assert.Equal(t, Slice(1), Concat(nil, Slice(), Slice(1)))
 	assert.Equal(t, Slice(1), Concat(Slice(1), Slice(), nil))
 }
 
 func TestDelete(t *testing.T) {
-	assert.Equal(t, Slice(1,2,4,5), Delete(Slice(1,2,3,4,5), 2, 1))
-}
\ No newline at end of file
+	assert.Equal(t, Slice(1, 2, 4, 5), Delete(Slice(1, 2, 3, 4, 5), 2, 1))
+}
+
+func TestDeepFlatten(t *testing.T) {
+	assert.Equal(t, Flatten(Slice(Slice(1, 2), 3, 4)), Slice(1, 2, 3, 4))
+	nestedSlice := Slice(Slice(1, Slice(Slice(2))), Slice(3, 4))
+	assert.Equal(t, DeepFlatten(nestedSlice, -1), Slice(1, 2, 3, 4))
+	assert.Equal(t, DeepFlatten(nestedSlice, 2), Slice(1, Slice(2), 3, 4))
+}