diff --git a/config/config.go b/config/config.go
index 97141bd4d34940e281f1b460756dad6781b4c7fb..7cf5780d159c7283fa4c5939cb374572cfcf8cc5 100644
--- a/config/config.go
+++ b/config/config.go
@@ -18,6 +18,7 @@ import (
 	"bytes"
 	"fmt"
 	"text/template"
+	lconfig "github.com/eris-ltd/eris-db/logging/config"
 )
 
 type ConfigServiceGeneral struct {
@@ -170,6 +171,9 @@ func GetConfigurationFileBytes(chainId, moniker, seeds string, chainImageName st
 	// write static section erismint
 	buffer.WriteString(sectionErisMint)
 
+	buffer.WriteString(sectionLoggingHeader)
+	buffer.WriteString(lconfig.DefaultNodeLoggingConfig().RootTOMLString())
+
 	return buffer.Bytes(), nil
 }
 
diff --git a/config/templates.go b/config/templates.go
index 433d8c8adec8e5c4ab05f695cc4e829ebebd9ea8..1573952be1661f2ffdaddaaed41eddc574007020 100644
--- a/config/templates.go
+++ b/config/templates.go
@@ -162,11 +162,6 @@ const sectionServers = `[servers]
 	rpc_local_address = "0.0.0.0:46657"
 	endpoint = "/websocket"
 
-  [servers.logging]
-  console_log_level = "info"
-  file_log_level = "warn"
-  log_file = ""
-
   `
 
 const separatorModules = `
@@ -296,3 +291,16 @@ db_backend = "leveldb"
 tendermint_host = "0.0.0.0:46657"
 
 `
+
+const sectionLoggingHeader = `
+################################################################################
+##
+## System-wide logging configuration
+##
+## Log messages are sent to one of two 'channels': info or trace
+##
+## They are delivered on two independent streams: 'info' or 'info and trace'
+##
+################################################################################
+
+`
\ No newline at end of file
diff --git a/config/viper.go b/config/viper.go
index cefd2f2a8f5ec3b0abc89dd83f0dafa0f6b60951..1b4c96b6caae6d840c26b2667ee499a1be1b643e 100644
--- a/config/viper.go
+++ b/config/viper.go
@@ -23,7 +23,7 @@ import (
 // Safely get the subtree from a viper config, returning an error if it could not
 // be obtained for any reason.
 func ViperSubConfig(conf *viper.Viper, configSubtreePath string) (subConfig *viper.Viper, err error) {
-	// Viper internally panics if `moduleName` contains an unallowed
+	// Viper internally panics if `moduleName` contains an disallowed
 	// character (eg, a dash).
 	defer func() {
 		if r := recover(); r != nil {
diff --git a/core/config.go b/core/config.go
index 70c20713171ade14d3afb25501a36c867df0e851..33544a29ad4482781fbf058b87ef1762a49278e7 100644
--- a/core/config.go
+++ b/core/config.go
@@ -114,13 +114,12 @@ func LoadServerConfig(do *definitions.Do) (*server.ServerConfig, error) {
 }
 
 func LoadLoggingConfigFromDo(do *definitions.Do) (*lconfig.LoggingConfig, error) {
-	//subConfig, err := SubConfig(conf, "logging")
-	loggingConfig := &lconfig.LoggingConfig{}
-	return loggingConfig, nil
+	loggingConfigMap := do.Config.GetStringMap("logging")
+	return lconfig.LoggingConfigFromMap(loggingConfigMap)
 }
 
 func LoadLoggingConfigFromClientDo(do *definitions.ClientDo) (*lconfig.LoggingConfig, error) {
-	loggingConfig := &lconfig.LoggingConfig{}
+	loggingConfig := lconfig.DefaultClientLoggingConfig()
 	return loggingConfig, nil
 }
 
diff --git a/glide.lock b/glide.lock
index 6887d752d90fc9ab64b4b6d7181b92262ed992d3..2336fc21fee7367ef4b69b2d799df2b240d0f3d1 100644
--- a/glide.lock
+++ b/glide.lock
@@ -86,7 +86,7 @@ imports:
 - name: github.com/mattn/go-isatty
   version: 30a891c33c7cde7b02a981314b4228ec99380cca
 - name: github.com/mitchellh/mapstructure
-  version: d2dd0262208475919e1a362f675cfc0e7c10e905
+  version: db1efb556f84b25a0a13a04aad883943538ad2e0
 - name: github.com/naoina/toml
   version: 751171607256bb66e64c9f0220c00662420c38e9
 - name: github.com/pmezard/go-difflib
diff --git a/logging/config/config.go b/logging/config/config.go
index f3921b062d8ef2ea37803cfa7e8e91f6abfd18fc..375d17589ab8cb5a4766b86065c78f129d054366 100644
--- a/logging/config/config.go
+++ b/logging/config/config.go
@@ -1,2 +1,80 @@
 package config
 
+import (
+	"bytes"
+
+	"fmt"
+
+	"github.com/BurntSushi/toml"
+	"github.com/eris-ltd/eris-db/logging/structure"
+)
+
+type LoggingConfig struct {
+	InfoSink         *SinkConfig `toml:"info_sink"`
+	InfoAndTraceSink *SinkConfig `toml:"info_and_trace_sink"`
+}
+
+// For encoding a top-level '[logging]' TOML table
+type LoggingConfigWrapper struct {
+	Logging *LoggingConfig `toml:"logging"`
+}
+
+func DefaultNodeLoggingConfig() *LoggingConfig {
+	return &LoggingConfig{
+		InfoSink:         Sink(),
+		InfoAndTraceSink: Sink().SetOutput(StderrOutput()),
+	}
+}
+
+func DefaultClientLoggingConfig() *LoggingConfig {
+	return &LoggingConfig{
+		// No output
+		InfoSink: Sink().
+			SetTransform(FilterTransform(ExcludeWhenAnyMatches,
+				structure.CapturedLoggingSourceKey, "")).
+			SetOutput(StderrOutput()),
+		InfoAndTraceSink: Sink(),
+	}
+}
+
+// Returns the TOML for a top-level logging config wrapped with [logging]
+func (lc *LoggingConfig) RootTOMLString() string {
+	return tomlString(LoggingConfigWrapper{lc})
+}
+
+func (lc *LoggingConfig) TOMLString() string {
+	return tomlString(lc)
+}
+
+func LoggingConfigFromMap(loggingRootMap map[string]interface{}) (*LoggingConfig, error) {
+	lc := new(LoggingConfig)
+	buf := new(bytes.Buffer)
+	enc := toml.NewEncoder(buf)
+	// TODO: [Silas] consider using strongly typed config/struct mapping everywhere
+	// (!! unfortunately the way we are using viper
+	// to pass around a untyped bag of config means that we don't get keys mapped
+	// according to their metadata `toml:"Name"` tags. So we are re-encoding to toml
+	// and then decoding into the strongly type struct as a work-around)
+	// Encode the map back to TOML
+	err := enc.Encode(loggingRootMap)
+	if err != nil {
+		return nil, err
+	}
+	// Decode into struct into the LoggingConfig struct
+	_, err = toml.Decode(buf.String(), lc)
+	if err != nil {
+		return nil, err
+	}
+	return lc, nil
+}
+
+func tomlString(v interface{}) string {
+	buf := new(bytes.Buffer)
+	encoder := toml.NewEncoder(buf)
+	err := encoder.Encode(v)
+	if err != nil {
+		// Seems like a reasonable compromise to make the string function clean
+		return fmt.Sprintf("Error encoding TOML: %s", err)
+	}
+	return buf.String()
+}
diff --git a/logging/config/config_test.go b/logging/config/config_test.go
index c4368dec9328dba9475beb53371cb7594f1274bc..5e30c7510dbcf0a497ad9eef36fc7b192ac6e058 100644
--- a/logging/config/config_test.go
+++ b/logging/config/config_test.go
@@ -1,12 +1,44 @@
 package config
 
 import (
+	"strings"
 	"testing"
+
+	"github.com/BurntSushi/toml"
 	"github.com/spf13/viper"
-	"strings"
+	"github.com/stretchr/testify/assert"
 )
 
-func TestUnmarshal(t *testing.T) {
+var complexConfig *LoggingConfig = &LoggingConfig{
+	InfoSink: Sink().
+		SetOutput(StderrOutput()),
+	InfoAndTraceSink: Sink().
+		SetTransform(LabelTransform(false, "Info", "Trace")).
+		AddSinks(
+			Sink().
+				SetOutput(StdoutOutput()).
+				SetTransform(FilterTransform(ExcludeWhenAnyMatches,
+					"Foo", "Bars")).
+				AddSinks(
+					Sink().
+						SetOutput(RemoteSyslogOutput("Eris-db", "tcp://example.com:6514")),
+					Sink().
+						SetOutput(StdoutOutput()),
+				),
+		),
+}
+
+func TestLoggingConfig_String(t *testing.T) {
+	lc := new(LoggingConfig)
+	toml.Decode(complexConfig.TOMLString(), lc)
+	assert.Equal(t, complexConfig, lc)
+}
+
+func TestReadViperConfig(t *testing.T) {
 	conf := viper.New()
-	conf.ReadConfig(strings.NewReader(``))
-}
\ No newline at end of file
+	conf.SetConfigType("toml")
+	conf.ReadConfig(strings.NewReader(complexConfig.TOMLString()))
+	lc, err := LoggingConfigFromMap(conf.AllSettings())
+	assert.NoError(t, err)
+	assert.Equal(t, complexConfig, lc)
+}
diff --git a/logging/config/sinks.go b/logging/config/sinks.go
index 25fe29eedf3e7dbd2933bc6398928946e1ed0885..89fbace405c93823f3bc4c8e8c6e95daaef0a5dc 100644
--- a/logging/config/sinks.go
+++ b/logging/config/sinks.go
@@ -4,8 +4,11 @@ import (
 	"fmt"
 	"os"
 
+	"net/url"
+
 	"github.com/eapache/channels"
 	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
 	kitlog "github.com/go-kit/kit/log"
 )
 
@@ -17,25 +20,29 @@ type filterMode string
 const (
 	// OutputType
 	NoOutput outputType = ""
-	Graylog  outputType = "Graylog"
-	Syslog   outputType = "Syslog"
-	File     outputType = "File"
-	Stdout   outputType = "Stdout"
-	Stderr   outputType = "Stderr"
+	Graylog  outputType = "graylog"
+	Syslog   outputType = "syslog"
+	File     outputType = "file"
+	Stdout   outputType = "stdout"
+	Stderr   outputType = "stderr"
 
 	// TransformType
 	NoTransform transformType = ""
 	// Filter log lines
-	Filter transformType = "Filter"
+	Filter transformType = "filter"
 	// Remove key-val pairs from each log line
-	Prune   transformType = "Prune"
-	Capture transformType = "Capture"
-	Label   transformType = "Label"
-
-	IncludeWhenAllMatch   filterMode = "IncludeWhenAllMatch"
-	IncludeWhenAnyMatches filterMode = "IncludeWhenAnyMatches"
-	ExcludeWhenAllMatch   filterMode = "ExcludeWhenAllMatch"
-	ExcludeWhenAnyMatches filterMode = "ExcludeWhenAnyMatches"
+	Prune transformType = "prune"
+	// Add key value pairs to each log linel
+	Label   transformType = "label"
+	Capture transformType = "capture"
+	// TODO [Silas]: add 'flush on exit' transform which flushes the buffer of
+	// CaptureLogger to its OutputLogger a non-passthrough capture when an exit
+	// signal is detected or some other exceptional thing happens
+
+	IncludeWhenAllMatch   filterMode = "include_when_all_match"
+	IncludeWhenAnyMatches filterMode = "include_when_any_matches"
+	ExcludeWhenAllMatch   filterMode = "exclude_when_all_match"
+	ExcludeWhenAnyMatches filterMode = "exclude_when_any_matches"
 )
 
 // Only include log lines matching the filter so negate the predicate in filter
@@ -75,14 +82,17 @@ type (
 	}
 
 	SyslogConfig struct {
+		Url string `toml:"url"`
+		Tag string `toml:"tag"`
 	}
 
 	FileConfig struct {
-		Path string
+		Path string `toml:"path"`
 	}
 
 	OutputConfig struct {
-		OutputType outputType
+		OutputType outputType `toml:"output_type"`
+		Format     string     `toml:"format,omitempty"`
 		*GraylogConfig
 		*FileConfig
 		*SyslogConfig
@@ -90,35 +100,39 @@ type (
 
 	// Transforms
 	LabelConfig struct {
-		Labels map[string]string
-		Prefix bool
+		Labels map[string]string `toml:"labels"`
+		Prefix bool              `toml:"prefix"`
+	}
+
+	PruneConfig struct {
+		Keys []string `toml:"keys"`
 	}
 
 	CaptureConfig struct {
-		Name        string
-		BufferCap   int
-		Passthrough bool
+		Name        string `toml:"name"`
+		BufferCap   int    `toml:"buffer_cap"`
+		Passthrough bool   `toml:"passthrough"`
 	}
 
 	// Generates true if KeyRegex matches a log line key and ValueRegex matches that key's value.
 	// If ValueRegex is empty then returns true if any key matches
 	// If KeyRegex is empty then returns true if any value matches
 	KeyValuePredicateConfig struct {
-		KeyRegex   string
-		ValueRegex string
+		KeyRegex   string `toml:"key_regex"`
+		ValueRegex string `toml:"value_regex"`
 	}
 
 	// Filter types
-
 	FilterConfig struct {
-		FilterMode filterMode
+		FilterMode filterMode `toml:"filter_mode"`
 		// Predicates to match a log line against using FilterMode
-		Predicates []*KeyValuePredicateConfig
+		Predicates []*KeyValuePredicateConfig `toml:"predicates"`
 	}
 
 	TransformConfig struct {
-		TransformType transformType
+		TransformType transformType `toml:"transform_type"`
 		*LabelConfig
+		*PruneConfig
 		*CaptureConfig
 		*FilterConfig
 	}
@@ -128,19 +142,13 @@ type (
 	// before transmitting its log it applies zero or one transforms to the stream of log lines.
 	// by chaining together many Sinks arbitrary transforms to and multi
 	SinkConfig struct {
-		Transform *TransformConfig
-		Sinks     []*SinkConfig
-		Output    *OutputConfig
-	}
-
-	LoggingConfig struct {
-		InfoSink         *SinkConfig
-		InfoAndTraceSink *SinkConfig
+		Transform *TransformConfig `toml:"transform"`
+		Sinks     []*SinkConfig    `toml:"sinks"`
+		Output    *OutputConfig    `toml:"output"`
 	}
 )
 
 // Builders
-
 func Sink() *SinkConfig {
 	return &SinkConfig{}
 }
@@ -165,18 +173,42 @@ func StdoutOutput() *OutputConfig {
 		OutputType: Stdout,
 	}
 }
+
 func StderrOutput() *OutputConfig {
 	return &OutputConfig{
 		OutputType: Stderr,
 	}
 }
 
+func SyslogOutput(tag string) *OutputConfig {
+	return RemoteSyslogOutput(tag, "")
+}
+
+func FileOutput(path string) *OutputConfig {
+	return &OutputConfig{
+		OutputType: File,
+		FileConfig: &FileConfig{
+			Path: path,
+		},
+	}
+}
+
+func RemoteSyslogOutput(tag, remoteUrl string) *OutputConfig {
+	return &OutputConfig{
+		OutputType: Syslog,
+		SyslogConfig: &SyslogConfig{
+			Url: remoteUrl,
+			Tag: tag,
+		},
+	}
+}
+
 func CaptureTransform(name string, bufferCap int, passthrough bool) *TransformConfig {
 	return &TransformConfig{
 		TransformType: Capture,
 		CaptureConfig: &CaptureConfig{
-			Name:      name,
-			BufferCap: bufferCap,
+			Name:        name,
+			BufferCap:   bufferCap,
 			Passthrough: passthrough,
 		},
 	}
@@ -216,12 +248,12 @@ func FilterTransform(fmode filterMode, keyvalueRegexes ...string) *TransformConf
 	}
 }
 
+// Logger formation
+
 func (sinkConfig *SinkConfig) BuildLogger() (kitlog.Logger, map[string]*loggers.CaptureLogger, error) {
 	return BuildLoggerFromSinkConfig(sinkConfig, make(map[string]*loggers.CaptureLogger))
 }
 
-// Logger formation
-
 func BuildLoggerFromSinkConfig(sinkConfig *SinkConfig,
 	captures map[string]*loggers.CaptureLogger) (kitlog.Logger, map[string]*loggers.CaptureLogger, error) {
 	if sinkConfig == nil {
@@ -258,13 +290,26 @@ func BuildOutputLogger(outputConfig *OutputConfig) (kitlog.Logger, error) {
 	case NoOutput:
 		return kitlog.NewNopLogger(), nil
 	//case Graylog:
-	//case Syslog:
+	case Syslog:
+		urlString := outputConfig.SyslogConfig.Url
+		if urlString != "" {
+			remoteUrl, err := url.Parse(urlString)
+			if err != nil {
+				return nil, fmt.Errorf("Error parsing remote syslog URL: %s, "+
+					"error: %s",
+					urlString, err)
+			}
+			return loggers.NewRemoteSyslogLogger(remoteUrl,
+				outputConfig.SyslogConfig.Tag, outputConfig.Format)
+		}
+		return loggers.NewSyslogLogger(outputConfig.SyslogConfig.Tag,
+			outputConfig.Format)
 	case Stdout:
-		return loggers.NewStreamLogger(os.Stdout), nil
+		return loggers.NewStreamLogger(os.Stdout, outputConfig.Format), nil
 	case Stderr:
-		return loggers.NewStreamLogger(os.Stderr), nil
+		return loggers.NewStreamLogger(os.Stderr, outputConfig.Format), nil
 	case File:
-		return loggers.NewFileLogger(outputConfig.FileConfig.Path)
+		return loggers.NewFileLogger(outputConfig.FileConfig.Path, outputConfig.Format)
 	default:
 		return nil, fmt.Errorf("Could not build logger for output: '%s'",
 			outputConfig.OutputType)
@@ -287,6 +332,12 @@ func BuildTransformLogger(transformConfig *TransformConfig,
 		} else {
 			return kitlog.NewContext(outputLogger).With(keyvals...), captures, nil
 		}
+	case Prune:
+		return kitlog.LoggerFunc(func(keyvals ...interface{}) error {
+			return outputLogger.Log(structure.RemoveKeys(keyvals,
+				transformConfig.PruneConfig.Keys))
+		}), captures, nil
+
 	case Capture:
 		name := transformConfig.CaptureConfig.Name
 		if _, ok := captures[name]; ok {
diff --git a/logging/config/sinks_test.go b/logging/config/sinks_test.go
index 8191369b90beddac720158423a8f4d790247f1f6..1465bb75d92fc1a85ade0f245058c476aa973af6 100644
--- a/logging/config/sinks_test.go
+++ b/logging/config/sinks_test.go
@@ -78,7 +78,18 @@ func TestFilterSinks(t *testing.T) {
 	logger.Log(ll[0]...)
 	assert.Equal(t, ll, included.BufferLogger().FlushLogLines())
 	assert.Equal(t, ll, excluded.BufferLogger().FlushLogLines())
+}
+
+func TestSyslogOutput(t *testing.T) {
+	_, _, err := Sink().SetOutput(RemoteSyslogOutput("Foo",
+		"tcp://logging.example.com:6514")).BuildLogger()
+	assert.Error(t, err)
+	assert.Equal(t, "dial tcp: lookup logging.example.com: no such host",
+		err.Error())
 
+	logger, _, err := Sink().SetOutput(SyslogOutput("Foo")).BuildLogger()
+	assert.NoError(t, err)
+	logger.Log("LogTo", "Syslog")
 }
 
 // Takes a variadic argument of log lines as a list of key value pairs delimited
diff --git a/logging/lifecycle/lifecycle.go b/logging/lifecycle/lifecycle.go
index 4bbbf31c1698e8e8ce526c73f85ab52a51e1d0a9..159062e3eb26a2acb19e0d64a23baeaaf667400c 100644
--- a/logging/lifecycle/lifecycle.go
+++ b/logging/lifecycle/lifecycle.go
@@ -41,7 +41,7 @@ func NewLoggerFromLoggingConfig(loggingConfig *config.LoggingConfig) (types.Info
 	if loggingConfig == nil {
 		return NewStdErrLogger(), nil
 	}
-	infoOnlyLogger, infoAndTraceLogger, err := infoTraceLoggersLoggingConfig(loggingConfig)
+	infoOnlyLogger, infoAndTraceLogger, err := infoTraceLoggersFromLoggingConfig(loggingConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -52,7 +52,7 @@ func NewLoggerFromLoggingConfig(loggingConfig *config.LoggingConfig) (types.Info
 // with those built from loggingConfig
 func SwapOutputLoggersFromLoggingConfig(logger types.InfoTraceLogger,
 	loggingConfig *config.LoggingConfig) error {
-	infoOnlyLogger, infoAndTraceLogger, err := infoTraceLoggersLoggingConfig(loggingConfig)
+	infoOnlyLogger, infoAndTraceLogger, err := infoTraceLoggersFromLoggingConfig(loggingConfig)
 	if err != nil {
 		return err
 	}
@@ -62,7 +62,7 @@ func SwapOutputLoggersFromLoggingConfig(logger types.InfoTraceLogger,
 }
 
 func NewStdErrLogger() types.InfoTraceLogger {
-	logger := loggers.NewStreamLogger(os.Stderr)
+	logger := loggers.NewStreamLogger(os.Stderr, "terminal")
 	return NewLogger(nil, logger)
 }
 
@@ -91,7 +91,7 @@ func CaptureStdlibLogOutput(infoTraceLogger types.InfoTraceLogger) {
 }
 
 // Helpers
-func infoTraceLoggersLoggingConfig(loggingConfig *config.LoggingConfig) (kitlog.Logger, kitlog.Logger, error) {
+func infoTraceLoggersFromLoggingConfig(loggingConfig *config.LoggingConfig) (kitlog.Logger, kitlog.Logger, error) {
 	infoOnlyLogger, _, err := loggingConfig.InfoSink.BuildLogger()
 	if err != nil {
 		return nil, nil, err
diff --git a/logging/loggers/tendermint_log15_loggers.go b/logging/loggers/tendermint_log15_loggers.go
index 62745d45b73b1c5f2095a99a23224fe2d636516d..815f2feb383e1d8bb9596b9db03566a461177b36 100644
--- a/logging/loggers/tendermint_log15_loggers.go
+++ b/logging/loggers/tendermint_log15_loggers.go
@@ -3,16 +3,52 @@ package loggers
 import (
 	"io"
 
+	"log/syslog"
+	"net/url"
+
+	log15a "github.com/eris-ltd/eris-db/logging/adapters/tendermint_log15"
 	kitlog "github.com/go-kit/kit/log"
 	"github.com/tendermint/log15"
-	log15a "github.com/eris-ltd/eris-db/logging/adapters/tendermint_log15"
 )
 
-func NewStreamLogger(writer io.Writer) kitlog.Logger {
-	return log15a.Log15HandlerAsKitLogger(log15.StreamHandler(writer, log15.TerminalFormat()))
+const syslogPriority = syslog.LOG_LOCAL0
+
+func NewStreamLogger(writer io.Writer, formatName string) kitlog.Logger {
+	return log15a.Log15HandlerAsKitLogger(log15.StreamHandler(writer,
+		format(formatName)))
 }
 
-func NewFileLogger(path string) (kitlog.Logger, error) {
-	handler, err := log15.FileHandler(path, log15.LogfmtFormat())
+func NewFileLogger(path string, formatName string) (kitlog.Logger, error) {
+	handler, err := log15.FileHandler(path, format(formatName))
 	return log15a.Log15HandlerAsKitLogger(handler), err
 }
+
+func NewRemoteSyslogLogger(url *url.URL, tag, formatName string) (kitlog.Logger, error) {
+	handler, err := log15.SyslogNetHandler(url.Scheme, url.Host, syslogPriority,
+		tag, format(formatName))
+	if err != nil {
+		return nil, err
+	}
+	return log15a.Log15HandlerAsKitLogger(handler), nil
+}
+
+func NewSyslogLogger(tag, formatName string) (kitlog.Logger, error) {
+	handler, err := log15.SyslogHandler(syslogPriority, tag, format(formatName))
+	if err != nil {
+		return nil, err
+	}
+	return log15a.Log15HandlerAsKitLogger(handler), nil
+}
+
+func format(name string) log15.Format {
+	switch name {
+	case "json":
+		return log15.JsonFormat()
+	case "logfmt":
+		return log15.LogfmtFormat()
+	case "terminal":
+		return log15.TerminalFormat()
+	default:
+		return log15.LogfmtFormat()
+	}
+}
diff --git a/logging/structure/structure.go b/logging/structure/structure.go
index 63bd0e16ff3b61ad119196e23414bac9600e332a..02155bc63820844696459d0fa764d6c4338444e0 100644
--- a/logging/structure/structure.go
+++ b/logging/structure/structure.go
@@ -46,6 +46,7 @@ const (
 // the unmatched remainder keyvals as context as a slice of key-values.
 func ValuesAndContext(keyvals []interface{},
 	keys ...interface{}) (map[interface{}]interface{}, []interface{}) {
+
 	vals := make(map[interface{}]interface{}, len(keys))
 	context := make([]interface{}, len(keyvals))
 	copy(context, keyvals)
@@ -72,6 +73,21 @@ func ValuesAndContext(keyvals []interface{},
 	return vals, context
 }
 
+// Drops all key value pairs where the key is in keys
+func RemoveKeys(keyvals []interface{}, keys ...interface{}) []interface{} {
+	keyvalsWithoutKeys := make([]interface{}, 0, len(keyvals))
+NEXT_KEYVAL:
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		for _, key := range keys {
+			if keyvals[i] == key {
+				continue NEXT_KEYVAL
+			}
+		}
+		keyvalsWithoutKeys = append(keyvalsWithoutKeys, keyvals[i], keyvals[i+1])
+	}
+	return keyvalsWithoutKeys
+}
+
 // 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
diff --git a/logging/structure/structure_test.go b/logging/structure/structure_test.go
index bbdd0895f348a8c6ceb99dca26470dce1b34e4ca..38da17bd774ce7cc1fd4786e667c3ccbb0178240 100644
--- a/logging/structure/structure_test.go
+++ b/logging/structure/structure_test.go
@@ -40,6 +40,7 @@ func TestVectorise(t *testing.T) {
 	)
 
 	kvsVector := Vectorise(kvs, "occupation", "scope")
+	// Vectorise scope
 	assert.Equal(t, Slice(
 		"scope", Slice("lawnmower", "hose pipe", "rake"),
 		"hub", "budub",
@@ -48,3 +49,24 @@ func TestVectorise(t *testing.T) {
 	),
 		kvsVector)
 }
+
+func TestRemoveKeys(t *testing.T) {
+	// Remove multiple of same key
+	assert.Equal(t, Slice("Fish", 9),
+		RemoveKeys(Slice("Foo", "Bar", "Fish", 9, "Foo", "Baz", "odd-key"),
+			"Foo"))
+
+	// Remove multiple different keys
+	assert.Equal(t, Slice("Fish", 9),
+		RemoveKeys(Slice("Foo", "Bar", "Fish", 9, "Foo", "Baz", "Bar", 89),
+			"Foo", "Bar"))
+
+	// Remove nothing but supply keys
+	assert.Equal(t, Slice("Foo", "Bar", "Fish", 9),
+		RemoveKeys(Slice("Foo", "Bar", "Fish", 9),
+			"A", "B", "C"))
+
+	// Remove nothing since no keys supplied
+	assert.Equal(t, Slice("Foo", "Bar", "Fish", 9),
+		RemoveKeys(Slice("Foo", "Bar", "Fish", 9)))
+}
diff --git a/net_test/data/local/server_conf.toml b/net_test/data/local/server_conf.toml
index e1fa06450446dcd9f91d6f3fac0744a94502ee86..903f0932ec63936b574eb50a639ca144ec427015 100644
--- a/net_test/data/local/server_conf.toml
+++ b/net_test/data/local/server_conf.toml
@@ -20,7 +20,3 @@ websocket_endpoint="/socketrpc"
 max_websocket_sessions=50
 read_buffer_size=4096
 write_buffer_size=4096
-[logging]
-console_log_level="info"
-file_log_level="warn"
-log_file=""
diff --git a/net_test/data/local_data/server_conf.toml b/net_test/data/local_data/server_conf.toml
index e1fa06450446dcd9f91d6f3fac0744a94502ee86..903f0932ec63936b574eb50a639ca144ec427015 100644
--- a/net_test/data/local_data/server_conf.toml
+++ b/net_test/data/local_data/server_conf.toml
@@ -20,7 +20,3 @@ websocket_endpoint="/socketrpc"
 max_websocket_sessions=50
 read_buffer_size=4096
 write_buffer_size=4096
-[logging]
-console_log_level="info"
-file_log_level="warn"
-log_file=""
diff --git a/net_test/data/net_test_0/server_conf.toml b/net_test/data/net_test_0/server_conf.toml
index e1fa06450446dcd9f91d6f3fac0744a94502ee86..903f0932ec63936b574eb50a639ca144ec427015 100644
--- a/net_test/data/net_test_0/server_conf.toml
+++ b/net_test/data/net_test_0/server_conf.toml
@@ -20,7 +20,3 @@ websocket_endpoint="/socketrpc"
 max_websocket_sessions=50
 read_buffer_size=4096
 write_buffer_size=4096
-[logging]
-console_log_level="info"
-file_log_level="warn"
-log_file=""
diff --git a/rpc/tendermint/test/config.go b/rpc/tendermint/test/config.go
index 06f3520e1dfb8ceb4edeaf7ae42eb01f204bedef..3bb69d07d827967916d45dc6eaafe1b4a001f70e 100644
--- a/rpc/tendermint/test/config.go
+++ b/rpc/tendermint/test/config.go
@@ -119,11 +119,6 @@ genesis_file = "genesis.json"
 	rpc_local_address = "0.0.0.0:36657"
 	endpoint = "/websocket"
 
-  [servers.logging]
-  console_log_level = "info"
-  file_log_level = "warn"
-  log_file = ""
-
 ################################################################################
 ################################################################################
 ##
diff --git a/server/config.go b/server/config.go
index 4dcce19dd18199cfbbd19ae0f54bed9554b8db53..7a7a60425c43f9a1305a2b26a243aaefc8cfa4ec 100644
--- a/server/config.go
+++ b/server/config.go
@@ -30,7 +30,6 @@ type (
 		HTTP       HTTP      `toml:"HTTP"`
 		WebSocket  WebSocket `toml:"web_socket"`
 		Tendermint Tendermint
-		Logging    Logging `toml:"logging"`
 	}
 
 	Bind struct {
@@ -70,12 +69,6 @@ type (
 		RpcLocalAddress string
 		Endpoint        string
 	}
-
-	Logging struct {
-		ConsoleLogLevel string `toml:"console_log_level"`
-		FileLogLevel    string `toml:"file_log_level"`
-		LogFile         string `toml:"log_file"`
-	}
 )
 
 func ReadServerConfig(viper *viper.Viper) (*ServerConfig, error) {
@@ -160,11 +153,6 @@ func ReadServerConfig(viper *viper.Viper) (*ServerConfig, error) {
 			RpcLocalAddress: viper.GetString("tendermint.rpc_local_address"),
 			Endpoint:        viper.GetString("tendermint.endpoint"),
 		},
-		Logging: Logging{
-			ConsoleLogLevel: viper.GetString("logging.console_log_level"),
-			FileLogLevel:    viper.GetString("logging.file_log_level"),
-			LogFile:         viper.GetString("logging.log_file"),
-		},
 	}, nil
 }
 
@@ -194,10 +182,5 @@ func DefaultServerConfig() *ServerConfig {
 			RpcLocalAddress: "0.0.0.0:46657",
 			Endpoint:        "/websocket",
 		},
-		Logging: Logging{
-			ConsoleLogLevel: "info",
-			FileLogLevel:    "warn",
-			LogFile:         "",
-		},
 	}
 }
diff --git a/server/logging.go b/server/logging.go
deleted file mode 100644
index 4a38e0f82d039b18400ec07d1767812e1210c574..0000000000000000000000000000000000000000
--- a/server/logging.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed 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 server
-
-import (
-	"fmt"
-	"os"
-
-	"github.com/tendermint/log15"
-)
-
-var rootHandler log15.Handler
-
-// This is basically the same code as in tendermint. Initialize root
-// and maybe later also track the loggers here.
-func InitLogger(config *ServerConfig) {
-
-	consoleLogLevel := config.Logging.ConsoleLogLevel
-
-	// stdout handler
-	handlers := []log15.Handler{}
-	stdoutHandler := log15.LvlFilterHandler(
-		getLevel(consoleLogLevel),
-		log15.StreamHandler(os.Stdout, log15.TerminalFormat()),
-	)
-	handlers = append(handlers, stdoutHandler)
-
-	if config.Logging.LogFile != "" {
-		fileLogLevel := config.Logging.FileLogLevel
-		fh, err := log15.FileHandler(config.Logging.LogFile, log15.LogfmtFormat())
-		if err != nil {
-			fmt.Println("Error creating log file: " + err.Error())
-			os.Exit(1)
-		}
-		fileHandler := log15.LvlFilterHandler(getLevel(fileLogLevel), fh)
-		handlers = append(handlers, fileHandler)
-	}
-
-	rootHandler = log15.MultiHandler(handlers...)
-
-	// By setting handlers on the root, we handle events from all loggers.
-	log15.Root().SetHandler(rootHandler)
-}
-
-// See binary/log for an example of usage.
-func RootHandler() log15.Handler {
-	return rootHandler
-}
-
-func New(ctx ...interface{}) log15.Logger {
-	return log15.Root().New(ctx...)
-}
-
-func getLevel(lvlString string) log15.Lvl {
-	lvl, err := log15.LvlFromString(lvlString)
-	if err != nil {
-		fmt.Printf("Invalid log level %v: %v", lvlString, err)
-		os.Exit(1)
-	}
-	return lvl
-}
diff --git a/server/server.go b/server/server.go
index 8e4c85122e663417e9355b099c9153442f70f9ae..e5ace66626958656c4bf57a3a66a9c5a24a95053 100644
--- a/server/server.go
+++ b/server/server.go
@@ -66,8 +66,6 @@ func (this *ServeProcess) Start() error {
 
 	config := this.config
 
-	InitLogger(config)
-
 	ch := NewCORSMiddleware(config.CORS)
 	router.Use(gin.Recovery(), logHandler, contentTypeMW, ch)