[lxc-devel] [lxd/master] Bugfixes and refactoring

stgraber on Github lxc-bot at linuxcontainers.org
Mon Apr 10 17:52:27 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170410/06e3efab/attachment.bin>
-------------- next part --------------
From 70025b6598c75ac50998ab7ac01865215744a1b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 5 Apr 2017 23:09:30 -0400
Subject: [PATCH 01/10] shared/logger: Create new package for logger
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

And move everything over to it.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 client.go                    |  11 +-
 lxc/exec.go                  |   6 +-
 lxc/exec_unix.go             |  54 ++++-----
 lxc/file.go                  |   3 +-
 lxc/main.go                  |   3 +-
 lxc/remote.go                |   3 +-
 lxd/api_internal.go          |   9 +-
 lxd/apparmor.go              |   5 +-
 lxd/certificates.go          |   7 +-
 lxd/container_exec.go        |  23 ++--
 lxd/container_lxc.go         | 263 ++++++++++++++++++++++---------------------
 lxd/container_put.go         |   5 +-
 lxd/containers.go            |   7 +-
 lxd/containers_get.go        |   8 +-
 lxd/containers_post.go       |  11 +-
 lxd/daemon.go                | 143 +++++++++++------------
 lxd/daemon_config.go         |   3 +-
 lxd/daemon_images.go         |  23 ++--
 lxd/db.go                    |  36 +++---
 lxd/db_containers.go         |   7 +-
 lxd/db_test.go               |   4 +-
 lxd/db_update.go             |  21 ++--
 lxd/debug.go                 |   6 +-
 lxd/devices.go               |  39 +++----
 lxd/devlxd.go                |   5 +-
 lxd/events.go                |   5 +-
 lxd/images.go                |  57 +++++-----
 lxd/main.go                  |   3 +-
 lxd/main_activateifneeded.go |  11 +-
 lxd/main_daemon.go           |   9 +-
 lxd/main_init.go             |   5 +-
 lxd/migrate.go               |   9 +-
 lxd/networks.go              |   3 +-
 lxd/operations.go            |  27 ++---
 lxd/patches.go               | 211 +++++++++++++++++-----------------
 lxd/profiles.go              |   5 +-
 lxd/rsync.go                 |   5 +-
 lxd/storage.go               |   3 +-
 lxd/storage_btrfs.go         | 143 +++++++++++------------
 lxd/storage_dir.go           |  69 ++++++------
 lxd/storage_lvm.go           | 177 ++++++++++++++---------------
 lxd/storage_mock.go          |  13 ++-
 lxd/storage_shared.go        |   7 +-
 lxd/storage_zfs.go           | 167 +++++++++++++--------------
 shared/json.go               |   6 +-
 shared/log.go                |  99 ----------------
 shared/log_debug.go          | 124 --------------------
 shared/logger/log.go         |  99 ++++++++++++++++
 shared/logger/log_debug.go   | 124 ++++++++++++++++++++
 shared/logging/log.go        |  10 +-
 shared/network.go            |  36 +++---
 shared/network_linux.go      |   8 +-
 shared/util_linux.go         |  20 ++--
 53 files changed, 1103 insertions(+), 1057 deletions(-)
 delete mode 100644 shared/log.go
 delete mode 100644 shared/log_debug.go
 create mode 100644 shared/logger/log.go
 create mode 100644 shared/logger/log_debug.go

diff --git a/client.go b/client.go
index f5ad18b..6a28d06 100644
--- a/client.go
+++ b/client.go
@@ -26,6 +26,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/simplestreams"
 	"github.com/lxc/lxd/shared/version"
 )
@@ -72,7 +73,7 @@ func ParseResponse(r *http.Response) (*api.Response, error) {
 	if err != nil {
 		return nil, err
 	}
-	shared.LogDebugf("Raw response: %s", string(s))
+	logger.Debugf("Raw response: %s", string(s))
 
 	if err := json.Unmarshal(s, &ret); err != nil {
 		return nil, err
@@ -381,7 +382,7 @@ func (c *Client) doUpdateMethod(method string, base string, args interface{}, rt
 		return nil, err
 	}
 
-	shared.LogDebugf("%s %s to %s", method, buf.String(), uri)
+	logger.Debugf("%s %s to %s", method, buf.String(), uri)
 
 	req, err := http.NewRequest(method, uri, &buf)
 	if err != nil {
@@ -530,7 +531,7 @@ func (c *Client) AmTrusted() bool {
 		return false
 	}
 
-	shared.LogDebugf("%s", resp)
+	logger.Debugf("%s", resp)
 
 	meta, err := resp.MetadataAsMap()
 	if err != nil {
@@ -551,7 +552,7 @@ func (c *Client) IsPublic() bool {
 		return false
 	}
 
-	shared.LogDebugf("%s", resp)
+	logger.Debugf("%s", resp)
 
 	meta, err := resp.MetadataAsMap()
 	if err != nil {
@@ -2497,7 +2498,7 @@ func (c *Client) SetProfileConfigItem(profile, key, value string) error {
 
 	st, err := c.ProfileConfig(profile)
 	if err != nil {
-		shared.LogDebugf("Error getting profile %s to update", profile)
+		logger.Debugf("Error getting profile %s to update", profile)
 		return err
 	}
 
diff --git a/lxc/exec.go b/lxc/exec.go
index 2b2ac0e..c1d0456 100644
--- a/lxc/exec.go
+++ b/lxc/exec.go
@@ -14,10 +14,10 @@ import (
 	"github.com/gorilla/websocket"
 
 	"github.com/lxc/lxd"
-	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/gnuflag"
 	"github.com/lxc/lxd/shared/i18n"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/termios"
 )
 
@@ -71,7 +71,7 @@ func (c *execCmd) sendTermSize(control *websocket.Conn) error {
 		return err
 	}
 
-	shared.LogDebugf("Window size is now: %dx%d", width, height)
+	logger.Debugf("Window size is now: %dx%d", width, height)
 
 	w, err := control.NextWriter(websocket.TextMessage)
 	if err != nil {
@@ -95,7 +95,7 @@ func (c *execCmd) sendTermSize(control *websocket.Conn) error {
 }
 
 func (c *execCmd) forwardSignal(control *websocket.Conn, sig syscall.Signal) error {
-	shared.LogDebugf("Forwarding signal: %s", sig)
+	logger.Debugf("Forwarding signal: %s", sig)
 
 	w, err := control.NextWriter(websocket.TextMessage)
 	if err != nil {
diff --git a/lxc/exec_unix.go b/lxc/exec_unix.go
index 89a0e04..7d36946 100644
--- a/lxc/exec_unix.go
+++ b/lxc/exec_unix.go
@@ -11,7 +11,7 @@ import (
 	"github.com/gorilla/websocket"
 
 	"github.com/lxc/lxd"
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func (c *execCmd) getStdout() io.WriteCloser {
@@ -46,94 +46,94 @@ func (c *execCmd) controlSocketHandler(d *lxd.Client, control *websocket.Conn) {
 		sig := <-ch
 		switch sig {
 		case syscall.SIGWINCH:
-			shared.LogDebugf("Received '%s signal', updating window geometry.", sig)
+			logger.Debugf("Received '%s signal', updating window geometry.", sig)
 			err := c.sendTermSize(control)
 			if err != nil {
-				shared.LogDebugf("error setting term size %s", err)
+				logger.Debugf("error setting term size %s", err)
 				return
 			}
 		case syscall.SIGTERM:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGTERM)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGTERM)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTERM)
 				return
 			}
 		case syscall.SIGHUP:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGHUP)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGHUP)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGHUP)
 				return
 			}
 		case syscall.SIGINT:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGINT)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGINT)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGINT)
 				return
 			}
 		case syscall.SIGQUIT:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGQUIT)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGQUIT)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGQUIT)
 				return
 			}
 		case syscall.SIGABRT:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGABRT)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGABRT)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGABRT)
 				return
 			}
 		case syscall.SIGTSTP:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGTSTP)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGTSTP)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTSTP)
 				return
 			}
 		case syscall.SIGTTIN:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGTTIN)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGTTIN)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTTIN)
 				return
 			}
 		case syscall.SIGTTOU:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGTTOU)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGTTOU)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGTTOU)
 				return
 			}
 		case syscall.SIGUSR1:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGUSR1)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGUSR1)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGUSR1)
 				return
 			}
 		case syscall.SIGUSR2:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGUSR2)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGUSR2)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGUSR2)
 				return
 			}
 		case syscall.SIGSEGV:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGSEGV)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGSEGV)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGSEGV)
 				return
 			}
 		case syscall.SIGCONT:
-			shared.LogDebugf("Received '%s signal', forwarding to executing program.", sig)
+			logger.Debugf("Received '%s signal', forwarding to executing program.", sig)
 			err := c.forwardSignal(control, syscall.SIGCONT)
 			if err != nil {
-				shared.LogDebugf("Failed to forward signal '%s'.", syscall.SIGCONT)
+				logger.Debugf("Failed to forward signal '%s'.", syscall.SIGCONT)
 				return
 			}
 		default:
diff --git a/lxc/file.go b/lxc/file.go
index b5bd93e..dc1051a 100644
--- a/lxc/file.go
+++ b/lxc/file.go
@@ -15,6 +15,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/gnuflag"
 	"github.com/lxc/lxd/shared/i18n"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/termios"
 )
 
@@ -95,7 +96,7 @@ func (c *fileCmd) push(config *lxd.Config, send_file_perms bool, args []string)
 		targetIsDir = true
 	}
 
-	shared.LogDebugf("Pushing to: %s  (isdir: %t)", targetPath, targetIsDir)
+	logger.Debugf("Pushing to: %s  (isdir: %t)", targetPath, targetIsDir)
 
 	d, err := lxd.NewClient(config, remote)
 	if err != nil {
diff --git a/lxc/main.go b/lxc/main.go
index 9570bff..1287d14 100644
--- a/lxc/main.go
+++ b/lxc/main.go
@@ -12,6 +12,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/gnuflag"
 	"github.com/lxc/lxd/shared/i18n"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
 )
 
@@ -119,7 +120,7 @@ func run() error {
 	os.Args = os.Args[1:]
 	gnuflag.Parse(true)
 
-	shared.Log, err = logging.GetLogger("", "", *verbose, *debug, nil)
+	logger.Log, err = logging.GetLogger("", "", *verbose, *debug, nil)
 	if err != nil {
 		return err
 	}
diff --git a/lxc/remote.go b/lxc/remote.go
index 6d6e725..1050721 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -20,6 +20,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/gnuflag"
 	"github.com/lxc/lxd/shared/i18n"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type remoteCmd struct {
@@ -307,7 +308,7 @@ func (c *remoteCmd) addServer(config *lxd.Config, server string, addr string, ac
 
 func (c *remoteCmd) removeCertificate(config *lxd.Config, remote string) {
 	certf := config.ServerCertPath(remote)
-	shared.LogDebugf("Trying to remove %s", certf)
+	logger.Debugf("Trying to remove %s", certf)
 
 	os.Remove(certf)
 }
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 739de54..f9627e9 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -15,6 +15,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -68,7 +69,7 @@ func internalContainerOnStart(d *Daemon, r *http.Request) Response {
 
 	err = c.OnStart()
 	if err != nil {
-		shared.Log.Error("start hook failed", log.Ctx{"container": c.Name(), "err": err})
+		logger.Error("start hook failed", log.Ctx{"container": c.Name(), "err": err})
 		return SmartError(err)
 	}
 
@@ -93,7 +94,7 @@ func internalContainerOnStop(d *Daemon, r *http.Request) Response {
 
 	err = c.OnStop(target)
 	if err != nil {
-		shared.Log.Error("stop hook failed", log.Ctx{"container": c.Name(), "err": err})
+		logger.Error("stop hook failed", log.Ctx{"container": c.Name(), "err": err})
 		return SmartError(err)
 	}
 
@@ -277,7 +278,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		// Kick out any snapshots that do not exist on-disk anymore.
 		_, ok := onDiskSnapshots[snap.Name]
 		if !ok {
-			shared.LogWarnf("The snapshot \"%s\" for container \"%s\" does not exist on disk anymore. Skipping...", snap.Name, req.Name)
+			logger.Warnf("The snapshot \"%s\" for container \"%s\" does not exist on disk anymore. Skipping...", snap.Name, req.Name)
 			continue
 		}
 
@@ -413,7 +414,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		// "backup.yaml" file. Recreate it by copying the parent
 		// container's settings.
 		if snap == nil {
-			shared.LogWarnf("The snapshot \"%s\" for the container \"%s\" exists on disk but not in the backup file. Restoring with parent container's settings.", snapName, req.Name)
+			logger.Warnf("The snapshot \"%s\" for the container \"%s\" exists on disk but not in the backup file. Restoring with parent container's settings.", snapName, req.Name)
 			snap = &api.ContainerSnapshot{}
 			snap.Config = backup.Container.Config
 			snap.CreationDate = backup.Container.CreatedAt
diff --git a/lxd/apparmor.go b/lxd/apparmor.go
index b11be5b..f4563b2 100644
--- a/lxd/apparmor.go
+++ b/lxd/apparmor.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -395,7 +396,7 @@ func runApparmor(command string, c container) error {
 	}...)
 
 	if err != nil {
-		shared.LogError("Running apparmor",
+		logger.Error("Running apparmor",
 			log.Ctx{"action": command, "output": output, "err": err})
 	}
 
@@ -472,7 +473,7 @@ func AADestroy(c container) error {
 	if aaStacking {
 		p := path.Join("/sys/kernel/security/apparmor/policy/namespaces", AANamespace(c))
 		if err := os.Remove(p); err != nil {
-			shared.LogError("error removing apparmor namespace", log.Ctx{"err": err, "ns": p})
+			logger.Error("error removing apparmor namespace", log.Ctx{"err": err, "ns": p})
 		}
 	}
 
diff --git a/lxd/certificates.go b/lxd/certificates.go
index 0f3c42e..46d5603 100644
--- a/lxd/certificates.go
+++ b/lxd/certificates.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -54,20 +55,20 @@ func readSavedClientCAList(d *Daemon) {
 
 	dbCerts, err := dbCertsGet(d.db)
 	if err != nil {
-		shared.LogInfof("Error reading certificates from database: %s", err)
+		logger.Infof("Error reading certificates from database: %s", err)
 		return
 	}
 
 	for _, dbCert := range dbCerts {
 		certBlock, _ := pem.Decode([]byte(dbCert.Certificate))
 		if certBlock == nil {
-			shared.LogInfof("Error decoding certificate for %s: %s", dbCert.Name, err)
+			logger.Infof("Error decoding certificate for %s: %s", dbCert.Name, err)
 			continue
 		}
 
 		cert, err := x509.ParseCertificate(certBlock.Bytes)
 		if err != nil {
-			shared.LogInfof("Error reading certificate for %s: %s", dbCert.Name, err)
+			logger.Infof("Error reading certificate for %s: %s", dbCert.Name, err)
 			continue
 		}
 		d.clientCerts = append(d.clientCerts, *cert)
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index cf3fed2..98d4a31 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -18,6 +18,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -160,7 +161,7 @@ func (s *execWs) Do(op *operation) error {
 				}
 
 				if err != nil {
-					shared.LogDebugf("Got error getting next reader %s", err)
+					logger.Debugf("Got error getting next reader %s", err)
 					er, ok := err.(*websocket.CloseError)
 					if !ok {
 						break
@@ -173,50 +174,50 @@ func (s *execWs) Do(op *operation) error {
 					// If an abnormal closure occured, kill the attached process.
 					err := syscall.Kill(attachedChildPid, syscall.SIGKILL)
 					if err != nil {
-						shared.LogDebugf("Failed to send SIGKILL to pid %d.", attachedChildPid)
+						logger.Debugf("Failed to send SIGKILL to pid %d.", attachedChildPid)
 					} else {
-						shared.LogDebugf("Sent SIGKILL to pid %d.", attachedChildPid)
+						logger.Debugf("Sent SIGKILL to pid %d.", attachedChildPid)
 					}
 					return
 				}
 
 				buf, err := ioutil.ReadAll(r)
 				if err != nil {
-					shared.LogDebugf("Failed to read message %s", err)
+					logger.Debugf("Failed to read message %s", err)
 					break
 				}
 
 				command := api.ContainerExecControl{}
 
 				if err := json.Unmarshal(buf, &command); err != nil {
-					shared.LogDebugf("Failed to unmarshal control socket command: %s", err)
+					logger.Debugf("Failed to unmarshal control socket command: %s", err)
 					continue
 				}
 
 				if command.Command == "window-resize" {
 					winchWidth, err := strconv.Atoi(command.Args["width"])
 					if err != nil {
-						shared.LogDebugf("Unable to extract window width: %s", err)
+						logger.Debugf("Unable to extract window width: %s", err)
 						continue
 					}
 
 					winchHeight, err := strconv.Atoi(command.Args["height"])
 					if err != nil {
-						shared.LogDebugf("Unable to extract window height: %s", err)
+						logger.Debugf("Unable to extract window height: %s", err)
 						continue
 					}
 
 					err = shared.SetSize(int(ptys[0].Fd()), winchWidth, winchHeight)
 					if err != nil {
-						shared.LogDebugf("Failed to set window size to: %dx%d", winchWidth, winchHeight)
+						logger.Debugf("Failed to set window size to: %dx%d", winchWidth, winchHeight)
 						continue
 					}
 				} else if command.Command == "signal" {
 					if err := syscall.Kill(attachedChildPid, syscall.Signal(command.Signal)); err != nil {
-						shared.LogDebugf("Failed forwarding signal '%s' to PID %d.", command.Signal, attachedChildPid)
+						logger.Debugf("Failed forwarding signal '%s' to PID %d.", command.Signal, attachedChildPid)
 						continue
 					}
-					shared.LogDebugf("Forwarded signal '%d' to PID %d.", command.Signal, attachedChildPid)
+					logger.Debugf("Forwarded signal '%d' to PID %d.", command.Signal, attachedChildPid)
 				}
 			}
 		}()
@@ -472,7 +473,7 @@ func containerExecPost(d *Daemon, r *http.Request) Response {
 
 		err = op.UpdateMetadata(metadata)
 		if err != nil {
-			shared.LogError("error updating metadata for cmd", log.Ctx{"err": err, "cmd": post.Command})
+			logger.Error("error updating metadata for cmd", log.Ctx{"err": err, "cmd": post.Command})
 		}
 
 		return cmdErr
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f9666ab..37ec833 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -27,6 +27,7 @@ import (
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -200,13 +201,13 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	ctxMap := log.Ctx{"name": c.name,
 		"ephemeral": c.ephemeral}
 
-	shared.LogInfo("Creating container", ctxMap)
+	logger.Info("Creating container", ctxMap)
 
 	// Load the config
 	err := c.init()
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
@@ -214,14 +215,14 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	err = containerValidConfig(d, c.expandedConfig, false, true)
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
 	err = containerValidDevices(d, c.expandedDevices, false, true)
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
@@ -264,7 +265,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	cStorage, err := storagePoolVolumeContainerCreateInit(d, storagePool, args.Name)
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed to initialize container storage", ctxMap)
+		logger.Error("Failed to initialize container storage", ctxMap)
 		return nil, err
 	}
 	c.storage = cStorage
@@ -283,7 +284,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 
 		if err != nil {
 			c.Delete()
-			shared.LogError("Failed creating container", ctxMap)
+			logger.Error("Failed creating container", ctxMap)
 			return nil, err
 		}
 	}
@@ -293,7 +294,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 		idmapBytes, err := json.Marshal(idmap.Idmap)
 		if err != nil {
 			c.Delete()
-			shared.LogError("Failed creating container", ctxMap)
+			logger.Error("Failed creating container", ctxMap)
 			return nil, err
 		}
 		jsonIdmap = string(idmapBytes)
@@ -304,14 +305,14 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	err = c.ConfigKeySet("volatile.idmap.next", jsonIdmap)
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
 	err = c.ConfigKeySet("volatile.idmap.base", fmt.Sprintf("%v", base))
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
@@ -320,7 +321,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 		err = c.ConfigKeySet("volatile.last_state.idmap", jsonIdmap)
 		if err != nil {
 			c.Delete()
-			shared.LogError("Failed creating container", ctxMap)
+			logger.Error("Failed creating container", ctxMap)
 			return nil, err
 		}
 	}
@@ -329,14 +330,14 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	err = c.init()
 	if err != nil {
 		c.Delete()
-		shared.LogError("Failed creating container", ctxMap)
+		logger.Error("Failed creating container", ctxMap)
 		return nil, err
 	}
 
 	// Update lease files
 	networkUpdateStatic(d, "")
 
-	shared.LogInfo("Created container", ctxMap)
+	logger.Info("Created container", ctxMap)
 
 	return c, nil
 }
@@ -1477,7 +1478,7 @@ func (c *containerLXC) setupUnixDevice(devType string, dev types.Device, major i
 
 	paths, err := c.createUnixDevice(temp)
 	if err != nil {
-		shared.LogDebug("failed to create device", log.Ctx{"err": err, "device": devType})
+		logger.Debug("failed to create device", log.Ctx{"err": err, "device": devType})
 		if createMustSucceed {
 			return err
 		}
@@ -1568,7 +1569,7 @@ func (c *containerLXC) startCommon() (string, error) {
 	}
 
 	if !reflect.DeepEqual(idmap, lastIdmap) {
-		shared.LogDebugf("Container idmap changed, remapping")
+		logger.Debugf("Container idmap changed, remapping")
 
 		ourStart, err := c.StorageStart()
 		if err != nil {
@@ -1935,7 +1936,7 @@ func (c *containerLXC) Start(stateful bool) error {
 		"used":      c.lastUsedDate,
 		"stateful":  stateful}
 
-	shared.LogInfo("Starting container", ctxMap)
+	logger.Info("Starting container", ctxMap)
 
 	// If stateful, restore now
 	if stateful {
@@ -1953,11 +1954,11 @@ func (c *containerLXC) Start(stateful bool) error {
 
 		err = dbContainerSetStateful(c.daemon.db, c.id, false)
 		if err != nil {
-			shared.LogError("Failed starting container", ctxMap)
+			logger.Error("Failed starting container", ctxMap)
 			return err
 		}
 
-		shared.LogInfo("Started container", ctxMap)
+		logger.Info("Started container", ctxMap)
 
 		return err
 	} else if c.stateful {
@@ -1985,7 +1986,7 @@ func (c *containerLXC) Start(stateful bool) error {
 	// Capture debug output
 	if out != "" {
 		for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") {
-			shared.LogDebugf("forkstart: %s", line)
+			logger.Debugf("forkstart: %s", line)
 		}
 	}
 
@@ -2017,13 +2018,13 @@ func (c *containerLXC) Start(stateful bool) error {
 			}
 		}
 
-		shared.LogError("Failed starting container", ctxMap)
+		logger.Error("Failed starting container", ctxMap)
 
 		// Return the actual error
 		return err
 	}
 
-	shared.LogInfo("Started container", ctxMap)
+	logger.Info("Started container", ctxMap)
 
 	return nil
 }
@@ -2089,7 +2090,7 @@ func (c *containerLXC) OnStart() error {
 			c.fromHook = false
 			err := c.setNetworkPriority()
 			if err != nil {
-				shared.LogError("Failed to apply network priority", log.Ctx{"container": c.name, "err": err})
+				logger.Error("Failed to apply network priority", log.Ctx{"container": c.name, "err": err})
 			}
 		}(c)
 	}
@@ -2109,7 +2110,7 @@ func (c *containerLXC) OnStart() error {
 			c.fromHook = false
 			err = c.setNetworkLimits(name, m)
 			if err != nil {
-				shared.LogError("Failed to apply network limits", log.Ctx{"container": c.name, "err": err})
+				logger.Error("Failed to apply network limits", log.Ctx{"container": c.name, "err": err})
 			}
 		}(c, name, m)
 	}
@@ -2145,7 +2146,7 @@ func (c *containerLXC) Stop(stateful bool) error {
 		"used":      c.lastUsedDate,
 		"stateful":  stateful}
 
-	shared.LogInfo("Stopping container", ctxMap)
+	logger.Info("Stopping container", ctxMap)
 
 	// Handle stateful stop
 	if stateful {
@@ -2156,7 +2157,7 @@ func (c *containerLXC) Stop(stateful bool) error {
 		err := os.MkdirAll(stateDir, 0700)
 		if err != nil {
 			op.Done(err)
-			shared.LogError("Failed stopping container", ctxMap)
+			logger.Error("Failed stopping container", ctxMap)
 			return err
 		}
 
@@ -2164,7 +2165,7 @@ func (c *containerLXC) Stop(stateful bool) error {
 		err = c.Migrate(lxc.MIGRATE_DUMP, stateDir, "snapshot", true, false)
 		if err != nil {
 			op.Done(err)
-			shared.LogError("Failed stopping container", ctxMap)
+			logger.Error("Failed stopping container", ctxMap)
 			return err
 		}
 
@@ -2172,12 +2173,12 @@ func (c *containerLXC) Stop(stateful bool) error {
 		err = dbContainerSetStateful(c.daemon.db, c.id, true)
 		if err != nil {
 			op.Done(err)
-			shared.LogError("Failed stopping container", ctxMap)
+			logger.Error("Failed stopping container", ctxMap)
 			return err
 		}
 
 		op.Done(nil)
-		shared.LogInfo("Stopped container", ctxMap)
+		logger.Info("Stopped container", ctxMap)
 		return nil
 	}
 
@@ -2185,7 +2186,7 @@ func (c *containerLXC) Stop(stateful bool) error {
 	err = c.initLXC()
 	if err != nil {
 		op.Done(err)
-		shared.LogError("Failed stopping container", ctxMap)
+		logger.Error("Failed stopping container", ctxMap)
 		return err
 	}
 
@@ -2204,17 +2205,17 @@ func (c *containerLXC) Stop(stateful bool) error {
 
 	if err := c.c.Stop(); err != nil {
 		op.Done(err)
-		shared.LogError("Failed stopping container", ctxMap)
+		logger.Error("Failed stopping container", ctxMap)
 		return err
 	}
 
 	err = op.Wait()
 	if err != nil && c.IsRunning() {
-		shared.LogError("Failed stopping container", ctxMap)
+		logger.Error("Failed stopping container", ctxMap)
 		return err
 	}
 
-	shared.LogInfo("Stopped container", ctxMap)
+	logger.Info("Stopped container", ctxMap)
 	return nil
 }
 
@@ -2239,29 +2240,29 @@ func (c *containerLXC) Shutdown(timeout time.Duration) error {
 		"used":      c.lastUsedDate,
 		"timeout":   timeout}
 
-	shared.LogInfo("Shutting down container", ctxMap)
+	logger.Info("Shutting down container", ctxMap)
 
 	// Load the go-lxc struct
 	err = c.initLXC()
 	if err != nil {
 		op.Done(err)
-		shared.LogError("Failed shutting down container", ctxMap)
+		logger.Error("Failed shutting down container", ctxMap)
 		return err
 	}
 
 	if err := c.c.Shutdown(timeout); err != nil {
 		op.Done(err)
-		shared.LogError("Failed shutting down container", ctxMap)
+		logger.Error("Failed shutting down container", ctxMap)
 		return err
 	}
 
 	err = op.Wait()
 	if err != nil && c.IsRunning() {
-		shared.LogError("Failed shutting down container", ctxMap)
+		logger.Error("Failed shutting down container", ctxMap)
 		return err
 	}
 
-	shared.LogInfo("Shut down container", ctxMap)
+	logger.Info("Shut down container", ctxMap)
 
 	return nil
 }
@@ -2269,7 +2270,7 @@ func (c *containerLXC) Shutdown(timeout time.Duration) error {
 func (c *containerLXC) OnStop(target string) error {
 	// Validate target
 	if !shared.StringInSlice(target, []string{"stop", "reboot"}) {
-		shared.LogError("Container sent invalid target to OnStop", log.Ctx{"container": c.Name(), "target": target})
+		logger.Error("Container sent invalid target to OnStop", log.Ctx{"container": c.Name(), "target": target})
 		return fmt.Errorf("Invalid stop target: %s", target)
 	}
 
@@ -2301,7 +2302,7 @@ func (c *containerLXC) OnStop(target string) error {
 			"used":      c.lastUsedDate,
 			"stateful":  false}
 
-		shared.LogInfo(fmt.Sprintf("Container initiated %s", target), ctxMap)
+		logger.Info(fmt.Sprintf("Container initiated %s", target), ctxMap)
 	}
 
 	go func(c *containerLXC, target string, op *lxcContainerOperation) {
@@ -2319,25 +2320,25 @@ func (c *containerLXC) OnStop(target string) error {
 		// Unload the apparmor profile
 		err = AADestroy(c)
 		if err != nil {
-			shared.LogError("Failed to destroy apparmor namespace", log.Ctx{"container": c.Name(), "err": err})
+			logger.Error("Failed to destroy apparmor namespace", log.Ctx{"container": c.Name(), "err": err})
 		}
 
 		// Clean all the unix devices
 		err = c.removeUnixDevices()
 		if err != nil {
-			shared.LogError("Unable to remove unix devices", log.Ctx{"container": c.Name(), "err": err})
+			logger.Error("Unable to remove unix devices", log.Ctx{"container": c.Name(), "err": err})
 		}
 
 		// Clean all the disk devices
 		err = c.removeDiskDevices()
 		if err != nil {
-			shared.LogError("Unable to remove disk devices", log.Ctx{"container": c.Name(), "err": err})
+			logger.Error("Unable to remove disk devices", log.Ctx{"container": c.Name(), "err": err})
 		}
 
 		// Clean all network filters
 		err = c.removeNetworkFilters()
 		if err != nil {
-			shared.LogError("Unable to remove network filters", log.Ctx{"container": c.Name(), "err": err})
+			logger.Error("Unable to remove network filters", log.Ctx{"container": c.Name(), "err": err})
 		}
 
 		// Reboot the container
@@ -2353,7 +2354,7 @@ func (c *containerLXC) OnStop(target string) error {
 		// Record current state
 		err = dbContainerSetState(c.daemon.db, c.id, "STOPPED")
 		if err != nil {
-			shared.LogError("Failed to set container state", log.Ctx{"container": c.Name(), "err": err})
+			logger.Error("Failed to set container state", log.Ctx{"container": c.Name(), "err": err})
 		}
 
 		// Destroy ephemeral containers
@@ -2382,24 +2383,24 @@ func (c *containerLXC) Freeze() error {
 		return fmt.Errorf("The container isn't running")
 	}
 
-	shared.LogInfo("Freezing container", ctxMap)
+	logger.Info("Freezing container", ctxMap)
 
 	// Load the go-lxc struct
 	err := c.initLXC()
 	if err != nil {
 		ctxMap["err"] = err
-		shared.LogError("Failed freezing container", ctxMap)
+		logger.Error("Failed freezing container", ctxMap)
 		return err
 	}
 
 	err = c.c.Freeze()
 	if err != nil {
 		ctxMap["err"] = err
-		shared.LogError("Failed freezing container", ctxMap)
+		logger.Error("Failed freezing container", ctxMap)
 		return err
 	}
 
-	shared.LogInfo("Froze container", ctxMap)
+	logger.Info("Froze container", ctxMap)
 
 	return err
 }
@@ -2420,21 +2421,21 @@ func (c *containerLXC) Unfreeze() error {
 		return fmt.Errorf("The container isn't running")
 	}
 
-	shared.LogInfo("Unfreezing container", ctxMap)
+	logger.Info("Unfreezing container", ctxMap)
 
 	// Load the go-lxc struct
 	err := c.initLXC()
 	if err != nil {
-		shared.LogError("Failed unfreezing container", ctxMap)
+		logger.Error("Failed unfreezing container", ctxMap)
 		return err
 	}
 
 	err = c.c.Unfreeze()
 	if err != nil {
-		shared.LogError("Failed unfreezing container", ctxMap)
+		logger.Error("Failed unfreezing container", ctxMap)
 	}
 
-	shared.LogInfo("Unfroze container", ctxMap)
+	logger.Info("Unfroze container", ctxMap)
 
 	return err
 }
@@ -2629,12 +2630,12 @@ func (c *containerLXC) Restore(sourceContainer container) error {
 		"used":      c.lastUsedDate,
 		"source":    sourceContainer.Name()}
 
-	shared.LogInfo("Restoring container", ctxMap)
+	logger.Info("Restoring container", ctxMap)
 
 	// Restore the rootfs
 	err = c.storage.ContainerRestore(c, sourceContainer)
 	if err != nil {
-		shared.LogError("Failed restoring container filesystem", ctxMap)
+		logger.Error("Failed restoring container filesystem", ctxMap)
 		return err
 	}
 
@@ -2649,7 +2650,7 @@ func (c *containerLXC) Restore(sourceContainer container) error {
 
 	err = c.Update(args, false)
 	if err != nil {
-		shared.LogError("Failed restoring container configuration", ctxMap)
+		logger.Error("Failed restoring container configuration", ctxMap)
 		return err
 	}
 
@@ -2664,7 +2665,7 @@ func (c *containerLXC) Restore(sourceContainer container) error {
 	// If the container wasn't running but was stateful, should we restore
 	// it as running?
 	if shared.PathExists(c.StatePath()) {
-		shared.LogDebug("Performing stateful restore", ctxMap)
+		logger.Debug("Performing stateful restore", ctxMap)
 		err := c.Migrate(lxc.MIGRATE_RESTORE, c.StatePath(), "snapshot", false, false)
 		if err != nil {
 			return err
@@ -2674,26 +2675,26 @@ func (c *containerLXC) Restore(sourceContainer container) error {
 		// this in snapshots.
 		err2 := os.RemoveAll(c.StatePath())
 		if err2 != nil {
-			shared.LogError("Failed to delete snapshot state", log.Ctx{"path": c.StatePath(), "err": err2})
+			logger.Error("Failed to delete snapshot state", log.Ctx{"path": c.StatePath(), "err": err2})
 		}
 
 		if err != nil {
-			shared.LogInfo("Failed restoring container", ctxMap)
+			logger.Info("Failed restoring container", ctxMap)
 			return err
 		}
 
-		shared.LogDebug("Performed stateful restore", ctxMap)
-		shared.LogInfo("Restored container", ctxMap)
+		logger.Debug("Performed stateful restore", ctxMap)
+		logger.Info("Restored container", ctxMap)
 		return nil
 	}
 
 	// Restart the container
 	if wasRunning {
-		shared.LogInfo("Restored container", ctxMap)
+		logger.Info("Restored container", ctxMap)
 		return c.Start(false)
 	}
 
-	shared.LogInfo("Restored container", ctxMap)
+	logger.Info("Restored container", ctxMap)
 
 	return nil
 }
@@ -2721,7 +2722,7 @@ func (c *containerLXC) Delete() error {
 		"ephemeral": c.ephemeral,
 		"used":      c.lastUsedDate}
 
-	shared.LogInfo("Deleting container", ctxMap)
+	logger.Info("Deleting container", ctxMap)
 
 	// Attempt to initialize storage interface for the container.
 	c.initStorage()
@@ -2730,14 +2731,14 @@ func (c *containerLXC) Delete() error {
 		// Remove the snapshot
 		if c.storage != nil {
 			if err := c.storage.ContainerSnapshotDelete(c); err != nil {
-				shared.LogWarn("Failed to delete snapshot", log.Ctx{"name": c.Name(), "err": err})
+				logger.Warn("Failed to delete snapshot", log.Ctx{"name": c.Name(), "err": err})
 				return err
 			}
 		}
 	} else {
 		// Remove all snapshot
 		if err := containerDeleteSnapshots(c.daemon, c.Name()); err != nil {
-			shared.LogWarn("Failed to delete snapshots", log.Ctx{"name": c.Name(), "err": err})
+			logger.Warn("Failed to delete snapshots", log.Ctx{"name": c.Name(), "err": err})
 			return err
 		}
 
@@ -2747,7 +2748,7 @@ func (c *containerLXC) Delete() error {
 		// Delete the container from disk
 		if shared.PathExists(c.Path()) && c.storage != nil {
 			if err := c.storage.ContainerDelete(c); err != nil {
-				shared.LogError("Failed deleting container storage", ctxMap)
+				logger.Error("Failed deleting container storage", ctxMap)
 				return err
 			}
 		}
@@ -2755,7 +2756,7 @@ func (c *containerLXC) Delete() error {
 
 	// Remove the database record
 	if err := dbContainerRemove(c.daemon.db, c.Name()); err != nil {
-		shared.LogError("Failed deleting container entry", ctxMap)
+		logger.Error("Failed deleting container entry", ctxMap)
 		return err
 	}
 
@@ -2788,7 +2789,7 @@ func (c *containerLXC) Delete() error {
 		networkClearLease(c.daemon, m["parent"], m["hwaddr"])
 	}
 
-	shared.LogInfo("Deleted container", ctxMap)
+	logger.Info("Deleted container", ctxMap)
 
 	return nil
 }
@@ -2801,7 +2802,7 @@ func (c *containerLXC) Rename(newName string) error {
 		"used":      c.lastUsedDate,
 		"newname":   newName}
 
-	shared.LogInfo("Renaming container", ctxMap)
+	logger.Info("Renaming container", ctxMap)
 
 	// Initialize storage interface for the container.
 	err := c.initStorage()
@@ -2826,7 +2827,7 @@ func (c *containerLXC) Rename(newName string) error {
 	if shared.PathExists(c.LogPath()) {
 		err := os.Rename(c.LogPath(), shared.LogPath(newName))
 		if err != nil {
-			shared.LogError("Failed renaming container", ctxMap)
+			logger.Error("Failed renaming container", ctxMap)
 			return err
 		}
 	}
@@ -2835,13 +2836,13 @@ func (c *containerLXC) Rename(newName string) error {
 	if c.IsSnapshot() {
 		err := c.storage.ContainerSnapshotRename(c, newName)
 		if err != nil {
-			shared.LogError("Failed renaming container", ctxMap)
+			logger.Error("Failed renaming container", ctxMap)
 			return err
 		}
 	} else {
 		err := c.storage.ContainerRename(c, newName)
 		if err != nil {
-			shared.LogError("Failed renaming container", ctxMap)
+			logger.Error("Failed renaming container", ctxMap)
 			return err
 		}
 	}
@@ -2849,7 +2850,7 @@ func (c *containerLXC) Rename(newName string) error {
 	// Rename the database entry
 	err = dbContainerRename(c.daemon.db, oldName, newName)
 	if err != nil {
-		shared.LogError("Failed renaming container", ctxMap)
+		logger.Error("Failed renaming container", ctxMap)
 		return err
 	}
 
@@ -2857,7 +2858,7 @@ func (c *containerLXC) Rename(newName string) error {
 	poolID, _ := c.storage.GetContainerPoolInfo()
 	err = dbStoragePoolVolumeRename(c.daemon.db, oldName, newName, storagePoolVolumeTypeContainer, poolID)
 	if err != nil {
-		shared.LogError("Failed renaming storage volume", ctxMap)
+		logger.Error("Failed renaming storage volume", ctxMap)
 		return err
 	}
 
@@ -2865,7 +2866,7 @@ func (c *containerLXC) Rename(newName string) error {
 		// Rename all the snapshots
 		results, err := dbContainerGetSnapshots(c.daemon.db, oldName)
 		if err != nil {
-			shared.LogError("Failed renaming container", ctxMap)
+			logger.Error("Failed renaming container", ctxMap)
 			return err
 		}
 
@@ -2875,14 +2876,14 @@ func (c *containerLXC) Rename(newName string) error {
 			newSnapshotName := newName + shared.SnapshotDelimiter + baseSnapName
 			err := dbContainerRename(c.daemon.db, sname, newSnapshotName)
 			if err != nil {
-				shared.LogError("Failed renaming container", ctxMap)
+				logger.Error("Failed renaming container", ctxMap)
 				return err
 			}
 
 			// Rename storage volume for the snapshot.
 			err = dbStoragePoolVolumeRename(c.daemon.db, sname, newSnapshotName, storagePoolVolumeTypeContainer, poolID)
 			if err != nil {
-				shared.LogError("Failed renaming storage volume", ctxMap)
+				logger.Error("Failed renaming storage volume", ctxMap)
 				return err
 			}
 		}
@@ -2898,7 +2899,7 @@ func (c *containerLXC) Rename(newName string) error {
 	// Invalidate the go-lxc cache
 	c.c = nil
 
-	shared.LogInfo("Renamed container", ctxMap)
+	logger.Info("Renamed container", ctxMap)
 
 	return nil
 }
@@ -2973,7 +2974,7 @@ func writeBackupFile(c container) error {
 
 	/* deal with the container occasionally not being monuted */
 	if !shared.PathExists(c.RootfsPath()) {
-		shared.LogWarn("Unable to update backup.yaml at this time.", log.Ctx{"name": c.Name()})
+		logger.Warn("Unable to update backup.yaml at this time.", log.Ctx{"name": c.Name()})
 		return nil
 	}
 
@@ -3674,7 +3675,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 
 					err := c.removeUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
 					if err != nil {
-						shared.LogError("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+						logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 						return err
 					}
 
@@ -3684,7 +3685,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 
 					err = c.removeUnixDeviceNum(m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
 					if err != nil {
-						shared.LogError("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+						logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 						return err
 					}
 				}
@@ -3706,7 +3707,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 						}
 						err = c.removeUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
 						if err != nil {
-							shared.LogError("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+							logger.Error("Failed to remove GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 							return err
 						}
 					}
@@ -3744,7 +3745,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 
 					err = c.insertUnixDeviceNum(m, usb.major, usb.minor, usb.path)
 					if err != nil {
-						shared.LogError("failed to insert usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
+						logger.Error("failed to insert usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
 					}
 				}
 			} else if m["type"] == "gpu" {
@@ -3766,7 +3767,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 
 					err = c.insertUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
 					if err != nil {
-						shared.LogError("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+						logger.Error("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 						return err
 					}
 
@@ -3776,7 +3777,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 
 					err = c.insertUnixDeviceNum(m, gpu.nvidia.major, gpu.nvidia.minor, gpu.nvidia.path)
 					if err != nil {
-						shared.LogError("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+						logger.Error("Failed to insert GPU device.", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 						return err
 					}
 
@@ -3790,7 +3791,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 						}
 						err = c.insertUnixDeviceNum(m, gpu.major, gpu.minor, gpu.path)
 						if err != nil {
-							shared.LogError("failed to insert GPU device", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
+							logger.Error("failed to insert GPU device", log.Ctx{"err": err, "gpu": gpu, "container": c.Name()})
 							return err
 						}
 					}
@@ -3927,12 +3928,12 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		return fmt.Errorf("Cannot export a running container as an image")
 	}
 
-	shared.LogInfo("Exporting container", ctxMap)
+	logger.Info("Exporting container", ctxMap)
 
 	// Start the storage
 	ourStart, err := c.StorageStart()
 	if err != nil {
-		shared.LogError("Failed exporting container", ctxMap)
+		logger.Error("Failed exporting container", ctxMap)
 		return err
 	}
 	if ourStart {
@@ -3942,13 +3943,13 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 	// Unshift the container
 	idmap, err := c.LastIdmapSet()
 	if err != nil {
-		shared.LogError("Failed exporting container", ctxMap)
+		logger.Error("Failed exporting container", ctxMap)
 		return err
 	}
 
 	if idmap != nil {
 		if err := idmap.UnshiftRootfs(c.RootfsPath()); err != nil {
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
@@ -3972,7 +3973,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 
 		err = c.tarStoreFile(linkmap, offset, tw, path, fi)
 		if err != nil {
-			shared.LogDebugf("Error tarring up %s: %s", path, err)
+			logger.Debugf("Error tarring up %s: %s", path, err)
 			return err
 		}
 		return nil
@@ -3985,7 +3986,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		tempDir, err := ioutil.TempDir("", "lxd_lxd_metadata_")
 		if err != nil {
 			tw.Close()
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 		defer os.RemoveAll(tempDir)
@@ -3997,7 +3998,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			parent, err := containerLoadByName(c.daemon, parentName)
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 
@@ -4009,7 +4010,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		if arch == "" {
 			arch, err = osarch.ArchitectureName(c.daemon.architectures[0])
 			if err != nil {
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 		}
@@ -4023,7 +4024,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		data, err := yaml.Marshal(&meta)
 		if err != nil {
 			tw.Close()
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
@@ -4032,22 +4033,22 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		err = ioutil.WriteFile(fnam, data, 0644)
 		if err != nil {
 			tw.Close()
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
 		fi, err := os.Lstat(fnam)
 		if err != nil {
 			tw.Close()
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
 		tmpOffset := len(path.Dir(fnam)) + 1
 		if err := c.tarStoreFile(linkmap, tmpOffset, tw, fnam, fi); err != nil {
 			tw.Close()
-			shared.LogDebugf("Error writing to tarfile: %s", err)
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Debugf("Error writing to tarfile: %s", err)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 	} else {
@@ -4056,7 +4057,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			content, err := ioutil.ReadFile(fnam)
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 
@@ -4064,7 +4065,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			err = yaml.Unmarshal(content, &metadata)
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 			metadata.Properties = properties
@@ -4073,7 +4074,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			tempDir, err := ioutil.TempDir("", "lxd_lxd_metadata_")
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 			defer os.RemoveAll(tempDir)
@@ -4081,7 +4082,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			data, err := yaml.Marshal(&metadata)
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 
@@ -4090,7 +4091,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 			err = ioutil.WriteFile(fnam, data, 0644)
 			if err != nil {
 				tw.Close()
-				shared.LogError("Failed exporting container", ctxMap)
+				logger.Error("Failed exporting container", ctxMap)
 				return err
 			}
 		}
@@ -4099,8 +4100,8 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		fi, err := os.Lstat(fnam)
 		if err != nil {
 			tw.Close()
-			shared.LogDebugf("Error statting %s during export", fnam)
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Debugf("Error statting %s during export", fnam)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 
@@ -4112,8 +4113,8 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		}
 		if err != nil {
 			tw.Close()
-			shared.LogDebugf("Error writing to tarfile: %s", err)
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Debugf("Error writing to tarfile: %s", err)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 	}
@@ -4122,7 +4123,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 	fnam = c.RootfsPath()
 	err = filepath.Walk(fnam, writeToTar)
 	if err != nil {
-		shared.LogError("Failed exporting container", ctxMap)
+		logger.Error("Failed exporting container", ctxMap)
 		return err
 	}
 
@@ -4131,18 +4132,18 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 	if shared.PathExists(fnam) {
 		err = filepath.Walk(fnam, writeToTar)
 		if err != nil {
-			shared.LogError("Failed exporting container", ctxMap)
+			logger.Error("Failed exporting container", ctxMap)
 			return err
 		}
 	}
 
 	err = tw.Close()
 	if err != nil {
-		shared.LogError("Failed exporting container", ctxMap)
+		logger.Error("Failed exporting container", ctxMap)
 		return err
 	}
 
-	shared.LogInfo("Exported container", ctxMap)
+	logger.Info("Exported container", ctxMap)
 	return nil
 }
 
@@ -4186,7 +4187,7 @@ func (c *containerLXC) Migrate(cmd uint, stateDir string, function string, stop
 		return fmt.Errorf("Unable to perform container live migration. CRIU isn't installed.")
 	}
 
-	shared.LogInfo("Migrating container", ctxMap)
+	logger.Info("Migrating container", ctxMap)
 
 	// Initialize storage interface for the container.
 	err = c.initStorage()
@@ -4204,7 +4205,7 @@ func (c *containerLXC) Migrate(cmd uint, stateDir string, function string, stop
 		prettyCmd = "restore"
 	default:
 		prettyCmd = "unknown"
-		shared.LogWarn("unknown migrate call", log.Ctx{"cmd": cmd})
+		logger.Warn("unknown migrate call", log.Ctx{"cmd": cmd})
 	}
 
 	preservesInodes := c.storage.PreservesInodes()
@@ -4272,7 +4273,7 @@ func (c *containerLXC) Migrate(cmd uint, stateDir string, function string, stop
 
 		if out != "" {
 			for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") {
-				shared.LogDebugf("forkmigrate: %s", line)
+				logger.Debugf("forkmigrate: %s", line)
 			}
 		}
 
@@ -4309,20 +4310,20 @@ func (c *containerLXC) Migrate(cmd uint, stateDir string, function string, stop
 
 	collectErr := collectCRIULogFile(c, stateDir, function, prettyCmd)
 	if collectErr != nil {
-		shared.LogError("Error collecting checkpoint log file", log.Ctx{"err": collectErr})
+		logger.Error("Error collecting checkpoint log file", log.Ctx{"err": collectErr})
 	}
 
 	if migrateErr != nil {
 		log, err2 := getCRIULogErrors(stateDir, prettyCmd)
 		if err2 == nil {
-			shared.LogInfo("Failed migrating container", ctxMap)
+			logger.Info("Failed migrating container", ctxMap)
 			migrateErr = fmt.Errorf("%s %s failed\n%s", function, prettyCmd, log)
 		}
 
 		return migrateErr
 	}
 
-	shared.LogInfo("Migrated container", ctxMap)
+	logger.Info("Migrated container", ctxMap)
 
 	return nil
 }
@@ -4517,7 +4518,7 @@ func (c *containerLXC) FileExists(path string) error {
 		}
 
 		for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") {
-			shared.LogDebugf("forkcheckfile: %s", line)
+			logger.Debugf("forkcheckfile: %s", line)
 		}
 	}
 
@@ -4627,7 +4628,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o
 			continue
 		}
 
-		shared.LogDebugf("forkgetfile: %s", line)
+		logger.Debugf("forkgetfile: %s", line)
 	}
 
 	if err != nil {
@@ -4817,7 +4818,7 @@ func (c *containerLXC) Exec(command []string, env map[string]string, stdin *os.F
 	r, w, err := shared.Pipe()
 	defer r.Close()
 	if err != nil {
-		shared.LogErrorf("s", err)
+		logger.Errorf("%s", err)
 		return nil, -1, -1, err
 	}
 
@@ -4831,7 +4832,7 @@ func (c *containerLXC) Exec(command []string, env map[string]string, stdin *os.F
 
 	attachedPid := -1
 	if err := json.NewDecoder(r).Decode(&attachedPid); err != nil {
-		shared.LogErrorf("Failed to retrieve PID of executing child process: %s", err)
+		logger.Errorf("Failed to retrieve PID of executing child process: %s", err)
 		return nil, -1, -1, err
 	}
 
@@ -4973,7 +4974,7 @@ func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork {
 
 	// Process forkgetnet response
 	if err != nil {
-		shared.LogError("Error calling 'lxd forkgetnet", log.Ctx{"container": c.name, "output": out, "pid": pid})
+		logger.Error("Error calling 'lxd forkgetnet", log.Ctx{"container": c.name, "output": out, "pid": pid})
 		return result
 	}
 
@@ -4981,7 +4982,7 @@ func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork {
 
 	err = json.Unmarshal([]byte(out), &networks)
 	if err != nil {
-		shared.LogError("Failure to read forkgetnet json", log.Ctx{"container": c.name, "err": err})
+		logger.Error("Failure to read forkgetnet json", log.Ctx{"container": c.name, "err": err})
 		return result
 	}
 
@@ -5205,7 +5206,7 @@ func (c *containerLXC) insertMount(source, target, fstype string, flags int) err
 
 	if out != "" {
 		for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") {
-			shared.LogDebugf("forkmount: %s", line)
+			logger.Debugf("forkmount: %s", line)
 		}
 	}
 
@@ -5230,7 +5231,7 @@ func (c *containerLXC) removeMount(mount string) error {
 
 	if out != "" {
 		for _, line := range strings.Split(strings.TrimRight(out, "\n"), "\n") {
-			shared.LogDebugf("forkumount: %s", line)
+			logger.Debugf("forkumount: %s", line)
 		}
 	}
 
@@ -5370,7 +5371,7 @@ func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
 		if idmapset != nil {
 			if err := idmapset.ShiftFile(devPath); err != nil {
 				// uidshift failing is weird, but not a big problem.  Log and proceed
-				shared.LogDebugf("Failed to uidshift device %s: %s\n", m["path"], err)
+				logger.Debugf("Failed to uidshift device %s: %s\n", m["path"], err)
 			}
 		}
 	} else {
@@ -5575,7 +5576,7 @@ func (c *containerLXC) removeUnixDeviceNum(m types.Device, major int, minor int,
 
 	err := c.removeUnixDevice(temp)
 	if err != nil {
-		shared.LogError("failed to remove device", log.Ctx{"err": err, m["type"]: path, "container": c.Name()})
+		logger.Error("failed to remove device", log.Ctx{"err": err, m["type"]: path, "container": c.Name()})
 		return err
 	}
 
@@ -5606,7 +5607,7 @@ func (c *containerLXC) removeUnixDevices() error {
 		devicePath := filepath.Join(c.DevicesPath(), f.Name())
 		err := os.Remove(devicePath)
 		if err != nil {
-			shared.LogError("failed removing unix device", log.Ctx{"err": err, "path": devicePath})
+			logger.Error("failed removing unix device", log.Ctx{"err": err, "path": devicePath})
 		}
 	}
 
@@ -6084,10 +6085,10 @@ func (c *containerLXC) createDiskDevice(name string, m types.Device) (string, er
 					volumeTypeName,
 					m["pool"], err)
 				if !isOptional {
-					shared.LogErrorf(msg)
+					logger.Errorf(msg)
 					return "", err
 				}
-				shared.LogWarnf(msg)
+				logger.Warnf(msg)
 			}
 		}
 	}
@@ -6262,7 +6263,7 @@ func (c *containerLXC) removeDiskDevices() error {
 		diskPath := filepath.Join(c.DevicesPath(), f.Name())
 		err := os.Remove(diskPath)
 		if err != nil {
-			shared.LogError("Failed to remove disk device path", log.Ctx{"err": err, "path": diskPath})
+			logger.Error("Failed to remove disk device path", log.Ctx{"err": err, "path": diskPath})
 		}
 	}
 
diff --git a/lxd/container_put.go b/lxd/container_put.go
index ec9c5c5..14640c2 100644
--- a/lxd/container_put.go
+++ b/lxd/container_put.go
@@ -10,6 +10,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -88,7 +89,7 @@ func containerSnapRestore(d *Daemon, name string, snap string) error {
 		snap = name + shared.SnapshotDelimiter + snap
 	}
 
-	shared.LogInfo(
+	logger.Info(
 		"RESTORE => Restoring snapshot",
 		log.Ctx{
 			"snapshot":  snap,
@@ -96,7 +97,7 @@ func containerSnapRestore(d *Daemon, name string, snap string) error {
 
 	c, err := containerLoadByName(d, name)
 	if err != nil {
-		shared.LogError(
+		logger.Error(
 			"RESTORE => loadcontainerLXD() failed",
 			log.Ctx{
 				"container": name,
diff --git a/lxd/containers.go b/lxd/containers.go
index 3bb06ae..3345879 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -180,7 +181,7 @@ func containersShutdown(d *Daemon) error {
 }
 
 func containerDeleteSnapshots(d *Daemon, cname string) error {
-	shared.LogDebug("containerDeleteSnapshots",
+	logger.Debug("containerDeleteSnapshots",
 		log.Ctx{"container": cname})
 
 	results, err := dbContainerGetSnapshots(d.db, cname)
@@ -191,7 +192,7 @@ func containerDeleteSnapshots(d *Daemon, cname string) error {
 	for _, sname := range results {
 		sc, err := containerLoadByName(d, sname)
 		if err != nil {
-			shared.LogError(
+			logger.Error(
 				"containerDeleteSnapshots: Failed to load the snapshotcontainer",
 				log.Ctx{"container": cname, "snapshot": sname})
 
@@ -199,7 +200,7 @@ func containerDeleteSnapshots(d *Daemon, cname string) error {
 		}
 
 		if err := sc.Delete(); err != nil {
-			shared.LogError(
+			logger.Error(
 				"containerDeleteSnapshots: Failed to delete a snapshotcontainer",
 				log.Ctx{"container": cname, "snapshot": sname, "err": err})
 		}
diff --git a/lxd/containers_get.go b/lxd/containers_get.go
index 2a10110..7255345 100644
--- a/lxd/containers_get.go
+++ b/lxd/containers_get.go
@@ -5,8 +5,8 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -17,7 +17,7 @@ func containersGet(d *Daemon, r *http.Request) Response {
 			return SyncResponse(true, result)
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("DBERR: containersGet: error %q", err)
+			logger.Debugf("DBERR: containersGet: error %q", err)
 			return InternalError(err)
 		}
 		// 1 s may seem drastic, but we really don't want to thrash
@@ -25,8 +25,8 @@ func containersGet(d *Daemon, r *http.Request) Response {
 		time.Sleep(100 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DBERR: containersGet, db is locked")
-	shared.PrintStack()
+	logger.Debugf("DBERR: containersGet, db is locked")
+	logger.PrintStack()
 	return InternalError(fmt.Errorf("DB is locked"))
 }
 
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 34e8ae2..a711281 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -14,6 +14,7 @@ import (
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -224,7 +225,7 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 		}
 	}
 
-	shared.LogDebugf("No valid storage pool in the container's local root disk device and profiles found.")
+	logger.Debugf("No valid storage pool in the container's local root disk device and profiles found.")
 	// If there is just a single pool in the database, use that
 	if storagePool == "" {
 		pools, err := dbStoragePools(d.db)
@@ -374,7 +375,7 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 		// And finally run the migration.
 		err = sink.Do(op)
 		if err != nil {
-			shared.LogError("Error during migration sink", log.Ctx{"err": err})
+			logger.Error("Error during migration sink", log.Ctx{"err": err})
 			c.Delete()
 			return fmt.Errorf("Error transferring container data: %s", err)
 		}
@@ -426,7 +427,7 @@ func createFromCopy(d *Daemon, req *api.ContainersPost) Response {
 
 	for key, value := range sourceConfig {
 		if len(key) > 8 && key[0:8] == "volatile" && !shared.StringInSlice(key[9:], []string{"base_image", "last_state.idmap"}) {
-			shared.LogDebug("Skipping volatile key from copy source",
+			logger.Debug("Skipping volatile key from copy source",
 				log.Ctx{"key": key})
 			continue
 		}
@@ -491,7 +492,7 @@ func createFromCopy(d *Daemon, req *api.ContainersPost) Response {
 }
 
 func containersPost(d *Daemon, r *http.Request) Response {
-	shared.LogDebugf("Responding to container create")
+	logger.Debugf("Responding to container create")
 
 	req := api.ContainersPost{}
 	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -522,7 +523,7 @@ func containersPost(d *Daemon, r *http.Request) Response {
 				return InternalError(fmt.Errorf("couldn't generate a new unique name after 100 tries"))
 			}
 		}
-		shared.LogDebugf("No name provided, creating %s", req.Name)
+		logger.Debugf("No name provided, creating %s", req.Name)
 	}
 
 	if req.Devices == nil {
diff --git a/lxd/daemon.go b/lxd/daemon.go
index f313ea3..cce17e7 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -31,6 +31,7 @@ import (
 
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
 	"github.com/lxc/lxd/shared/osarch"
 	"github.com/lxc/lxd/shared/version"
@@ -150,7 +151,7 @@ func (d *Daemon) httpClient(certificate string) (*http.Client, error) {
 func readMyCert() (string, string, error) {
 	certf := shared.VarPath("server.crt")
 	keyf := shared.VarPath("server.key")
-	shared.LogDebug("Looking for existing certificates", log.Ctx{"cert": certf, "key": keyf})
+	logger.Debug("Looking for existing certificates", log.Ctx{"cert": certf, "key": keyf})
 	err := shared.FindOrGenCert(certf, keyf, false)
 
 	return certf, keyf, err
@@ -209,19 +210,19 @@ func (d *Daemon) createCmd(version string, c Command) {
 		w.Header().Set("Content-Type", "application/json")
 
 		if d.isTrustedClient(r) {
-			shared.LogDebug(
+			logger.Debug(
 				"handling",
 				log.Ctx{"method": r.Method, "url": r.URL.RequestURI(), "ip": r.RemoteAddr})
 		} else if r.Method == "GET" && c.untrustedGet {
-			shared.LogDebug(
+			logger.Debug(
 				"allowing untrusted GET",
 				log.Ctx{"url": r.URL.RequestURI(), "ip": r.RemoteAddr})
 		} else if r.Method == "POST" && c.untrustedPost {
-			shared.LogDebug(
+			logger.Debug(
 				"allowing untrusted POST",
 				log.Ctx{"url": r.URL.RequestURI(), "ip": r.RemoteAddr})
 		} else {
-			shared.LogWarn(
+			logger.Warn(
 				"rejecting request from untrusted client",
 				log.Ctx{"ip": r.RemoteAddr})
 			Forbidden.Render(w)
@@ -272,7 +273,7 @@ func (d *Daemon) createCmd(version string, c Command) {
 		if err := resp.Render(w); err != nil {
 			err := InternalError(err).Render(w)
 			if err != nil {
-				shared.LogErrorf("Failed writing error for error, giving up")
+				logger.Errorf("Failed writing error for error, giving up")
 			}
 		}
 
@@ -294,10 +295,10 @@ func (d *Daemon) SetupStorageDriver(forceCheck bool) error {
 	pools, err := dbStoragePools(d.db)
 	if err != nil {
 		if err == NoSuchObjectError {
-			shared.LogDebugf("No existing storage pools detected.")
+			logger.Debugf("No existing storage pools detected.")
 			return nil
 		}
-		shared.LogDebugf("Failed to retrieve existing storage pools.")
+		logger.Debugf("Failed to retrieve existing storage pools.")
 		return err
 	}
 
@@ -314,17 +315,17 @@ func (d *Daemon) SetupStorageDriver(forceCheck bool) error {
 		}
 
 		if !shared.StringInSlice("storage_api", appliedPatches) {
-			shared.LogWarnf("Incorrectly applied \"storage_api\" patch. Skipping storage pool initialization as it might be corrupt.")
+			logger.Warnf("Incorrectly applied \"storage_api\" patch. Skipping storage pool initialization as it might be corrupt.")
 			return nil
 		}
 
 	}
 
 	for _, pool := range pools {
-		shared.LogDebugf("Initializing and checking storage pool \"%s\".", pool)
+		logger.Debugf("Initializing and checking storage pool \"%s\".", pool)
 		s, err := storagePoolInit(d, pool)
 		if err != nil {
-			shared.LogErrorf("Error initializing storage pool \"%s\": %s. Correct functionality of the storage pool cannot be guaranteed.", pool, err)
+			logger.Errorf("Error initializing storage pool \"%s\": %s. Correct functionality of the storage pool cannot be guaranteed.", pool, err)
 			continue
 		}
 
@@ -522,8 +523,8 @@ func (d *Daemon) Init() error {
 	}
 
 	/* Setup logging if that wasn't done before */
-	if shared.Log == nil {
-		shared.Log, err = logging.GetLogger("", "", true, true, nil)
+	if logger.Log == nil {
+		logger.Log, err = logging.GetLogger("", "", true, true, nil)
 		if err != nil {
 			return err
 		}
@@ -531,13 +532,13 @@ func (d *Daemon) Init() error {
 
 	/* Print welcome message */
 	if d.MockMode {
-		shared.LogInfo(fmt.Sprintf("LXD %s is starting in mock mode", version.Version),
+		logger.Info(fmt.Sprintf("LXD %s is starting in mock mode", version.Version),
 			log.Ctx{"path": shared.VarPath("")})
 	} else if d.SetupMode {
-		shared.LogInfo(fmt.Sprintf("LXD %s is starting in setup mode", version.Version),
+		logger.Info(fmt.Sprintf("LXD %s is starting in setup mode", version.Version),
 			log.Ctx{"path": shared.VarPath("")})
 	} else {
-		shared.LogInfo(fmt.Sprintf("LXD %s is starting in normal mode", version.Version),
+		logger.Info(fmt.Sprintf("LXD %s is starting in normal mode", version.Version),
 			log.Ctx{"path": shared.VarPath("")})
 	}
 
@@ -548,31 +549,31 @@ func (d *Daemon) Init() error {
 	if aaAvailable && os.Getenv("LXD_SECURITY_APPARMOR") == "false" {
 		aaAvailable = false
 		aaAdmin = false
-		shared.LogWarnf("AppArmor support has been manually disabled")
+		logger.Warnf("AppArmor support has been manually disabled")
 	}
 
 	if aaAvailable && !shared.IsDir("/sys/kernel/security/apparmor") {
 		aaAvailable = false
 		aaAdmin = false
-		shared.LogWarnf("AppArmor support has been disabled because of lack of kernel support")
+		logger.Warnf("AppArmor support has been disabled because of lack of kernel support")
 	}
 
 	_, err = exec.LookPath("apparmor_parser")
 	if aaAvailable && err != nil {
 		aaAvailable = false
 		aaAdmin = false
-		shared.LogWarnf("AppArmor support has been disabled because 'apparmor_parser' couldn't be found")
+		logger.Warnf("AppArmor support has been disabled because 'apparmor_parser' couldn't be found")
 	}
 
 	/* Detect AppArmor admin support */
 	if aaAdmin && !haveMacAdmin() {
 		aaAdmin = false
-		shared.LogWarnf("Per-container AppArmor profiles are disabled because the mac_admin capability is missing.")
+		logger.Warnf("Per-container AppArmor profiles are disabled because the mac_admin capability is missing.")
 	}
 
 	if aaAdmin && runningInUserns {
 		aaAdmin = false
-		shared.LogWarnf("Per-container AppArmor profiles are disabled because LXD is running in an unprivileged container.")
+		logger.Warnf("Per-container AppArmor profiles are disabled because LXD is running in an unprivileged container.")
 	}
 
 	/* Detect AppArmor confinment */
@@ -580,7 +581,7 @@ func (d *Daemon) Init() error {
 		profile := aaProfile()
 		if profile != "unconfined" && profile != "" {
 			aaConfined = true
-			shared.LogWarnf("Per-container AppArmor profiles are disabled because LXD is already protected by AppArmor.")
+			logger.Warnf("Per-container AppArmor profiles are disabled because LXD is already protected by AppArmor.")
 		}
 	}
 
@@ -605,13 +606,13 @@ func (d *Daemon) Init() error {
 			parts := strings.Split(strings.TrimSpace(content), ".")
 
 			if len(parts) == 0 {
-				shared.LogWarn("unknown apparmor domain version", log.Ctx{"version": content})
+				logger.Warn("unknown apparmor domain version", log.Ctx{"version": content})
 				return false
 			}
 
 			major, err := strconv.Atoi(parts[0])
 			if err != nil {
-				shared.LogWarn("unknown apparmor domain version", log.Ctx{"version": content})
+				logger.Warn("unknown apparmor domain version", log.Ctx{"version": content})
 				return false
 			}
 
@@ -619,7 +620,7 @@ func (d *Daemon) Init() error {
 			if len(parts) == 2 {
 				minor, err = strconv.Atoi(parts[1])
 				if err != nil {
-					shared.LogWarn("unknown apparmor domain version", log.Ctx{"version": content})
+					logger.Warn("unknown apparmor domain version", log.Ctx{"version": content})
 					return false
 				}
 			}
@@ -633,47 +634,47 @@ func (d *Daemon) Init() error {
 	/* Detect CGroup support */
 	cgBlkioController = shared.PathExists("/sys/fs/cgroup/blkio/")
 	if !cgBlkioController {
-		shared.LogWarnf("Couldn't find the CGroup blkio controller, I/O limits will be ignored.")
+		logger.Warnf("Couldn't find the CGroup blkio controller, I/O limits will be ignored.")
 	}
 
 	cgCpuController = shared.PathExists("/sys/fs/cgroup/cpu/")
 	if !cgCpuController {
-		shared.LogWarnf("Couldn't find the CGroup CPU controller, CPU time limits will be ignored.")
+		logger.Warnf("Couldn't find the CGroup CPU controller, CPU time limits will be ignored.")
 	}
 
 	cgCpuacctController = shared.PathExists("/sys/fs/cgroup/cpuacct/")
 	if !cgCpuacctController {
-		shared.LogWarnf("Couldn't find the CGroup CPUacct controller, CPU accounting will not be available.")
+		logger.Warnf("Couldn't find the CGroup CPUacct controller, CPU accounting will not be available.")
 	}
 
 	cgCpusetController = shared.PathExists("/sys/fs/cgroup/cpuset/")
 	if !cgCpusetController {
-		shared.LogWarnf("Couldn't find the CGroup CPUset controller, CPU pinning will be ignored.")
+		logger.Warnf("Couldn't find the CGroup CPUset controller, CPU pinning will be ignored.")
 	}
 
 	cgDevicesController = shared.PathExists("/sys/fs/cgroup/devices/")
 	if !cgDevicesController {
-		shared.LogWarnf("Couldn't find the CGroup devices controller, device access control won't work.")
+		logger.Warnf("Couldn't find the CGroup devices controller, device access control won't work.")
 	}
 
 	cgMemoryController = shared.PathExists("/sys/fs/cgroup/memory/")
 	if !cgMemoryController {
-		shared.LogWarnf("Couldn't find the CGroup memory controller, memory limits will be ignored.")
+		logger.Warnf("Couldn't find the CGroup memory controller, memory limits will be ignored.")
 	}
 
 	cgNetPrioController = shared.PathExists("/sys/fs/cgroup/net_prio/")
 	if !cgNetPrioController {
-		shared.LogWarnf("Couldn't find the CGroup network class controller, network limits will be ignored.")
+		logger.Warnf("Couldn't find the CGroup network class controller, network limits will be ignored.")
 	}
 
 	cgPidsController = shared.PathExists("/sys/fs/cgroup/pids/")
 	if !cgPidsController {
-		shared.LogWarnf("Couldn't find the CGroup pids controller, process limits will be ignored.")
+		logger.Warnf("Couldn't find the CGroup pids controller, process limits will be ignored.")
 	}
 
 	cgSwapAccounting = shared.PathExists("/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes")
 	if !cgSwapAccounting {
-		shared.LogWarnf("CGroup memory swap accounting is disabled, swap limits will be ignored.")
+		logger.Warnf("CGroup memory swap accounting is disabled, swap limits will be ignored.")
 	}
 
 	/* Get the list of supported architectures */
@@ -746,30 +747,30 @@ func (d *Daemon) Init() error {
 	/* Detect the filesystem */
 	d.BackingFs, err = filesystemDetect(d.lxcpath)
 	if err != nil {
-		shared.LogError("Error detecting backing fs", log.Ctx{"err": err})
+		logger.Error("Error detecting backing fs", log.Ctx{"err": err})
 	}
 
 	/* Read the uid/gid allocation */
 	d.IdmapSet, err = shared.DefaultIdmapSet()
 	if err != nil {
-		shared.LogWarn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
-		shared.LogWarnf("Only privileged containers will be able to run")
+		logger.Warn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
+		logger.Warnf("Only privileged containers will be able to run")
 		d.IdmapSet = nil
 	} else {
 		kernelIdmapSet, err := shared.CurrentIdmapSet()
 		if err == nil {
-			shared.LogInfof("Kernel uid/gid map:")
+			logger.Infof("Kernel uid/gid map:")
 			for _, lxcmap := range kernelIdmapSet.ToLxcString() {
-				shared.LogInfof(strings.TrimRight(" - "+lxcmap, "\n"))
+				logger.Infof(strings.TrimRight(" - "+lxcmap, "\n"))
 			}
 		}
 
 		if len(d.IdmapSet.Idmap) == 0 {
-			shared.LogWarnf("No available uid/gid map could be found")
-			shared.LogWarnf("Only privileged containers will be able to run")
+			logger.Warnf("No available uid/gid map could be found")
+			logger.Warnf("Only privileged containers will be able to run")
 			d.IdmapSet = nil
 		} else {
-			shared.LogInfof("Configured LXD uid/gid map:")
+			logger.Infof("Configured LXD uid/gid map:")
 			for _, lxcmap := range d.IdmapSet.Idmap {
 				suffix := ""
 
@@ -778,14 +779,14 @@ func (d *Daemon) Init() error {
 				}
 
 				for _, lxcEntry := range lxcmap.ToLxcString() {
-					shared.LogInfof(" - %s%s", strings.TrimRight(lxcEntry, "\n"), suffix)
+					logger.Infof(" - %s%s", strings.TrimRight(lxcEntry, "\n"), suffix)
 				}
 			}
 
 			err = d.IdmapSet.Usable()
 			if err != nil {
-				shared.LogWarnf("One or more uid/gid map entry isn't usable (typically due to nesting)")
-				shared.LogWarnf("Only privileged containers will be able to run")
+				logger.Warnf("One or more uid/gid map entry isn't usable (typically due to nesting)")
+				logger.Warnf("Only privileged containers will be able to run")
 				d.IdmapSet = nil
 			}
 		}
@@ -833,14 +834,14 @@ func (d *Daemon) Init() error {
 	go func() {
 		t := time.NewTicker(24 * time.Hour)
 		for {
-			shared.LogInfof("Expiring log files")
+			logger.Infof("Expiring log files")
 
 			err := d.ExpireLogs()
 			if err != nil {
-				shared.LogError("Failed to expire logs", log.Ctx{"err": err})
+				logger.Error("Failed to expire logs", log.Ctx{"err": err})
 			}
 
-			shared.LogInfof("Done expiring log files")
+			logger.Infof("Done expiring log files")
 			<-t.C
 		}
 	}()
@@ -864,7 +865,7 @@ func (d *Daemon) Init() error {
 	}
 
 	/* Setup /dev/lxd */
-	shared.LogInfof("Starting /dev/lxd handler")
+	logger.Infof("Starting /dev/lxd handler")
 	d.devlxd, err = createAndBindDevLxd()
 	if err != nil {
 		return err
@@ -912,7 +913,7 @@ func (d *Daemon) Init() error {
 			tlsConfig.RootCAs = caPool
 			tlsConfig.ClientCAs = caPool
 
-			shared.LogInfof("LXD is in CA mode, only CA-signed certificates will be allowed")
+			logger.Infof("LXD is in CA mode, only CA-signed certificates will be allowed")
 		}
 
 		tlsConfig.BuildNameToCertificate()
@@ -940,7 +941,7 @@ func (d *Daemon) Init() error {
 	}
 
 	d.mux.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		shared.LogInfo("Sending top level 404", log.Ctx{"url": r.URL})
+		logger.Info("Sending top level 404", log.Ctx{"url": r.URL})
 		w.Header().Set("Content-Type", "application/json")
 		NotFound.Render(w)
 	})
@@ -948,7 +949,7 @@ func (d *Daemon) Init() error {
 	// Prepare the list of listeners
 	listeners := d.GetListeners()
 	if len(listeners) > 0 {
-		shared.LogInfof("LXD is socket activated")
+		logger.Infof("LXD is socket activated")
 
 		for _, listener := range listeners {
 			if shared.PathExists(listener.Addr().String()) {
@@ -959,7 +960,7 @@ func (d *Daemon) Init() error {
 			}
 		}
 	} else {
-		shared.LogInfof("LXD isn't socket activated")
+		logger.Infof("LXD isn't socket activated")
 
 		localSocketPath := shared.VarPath("unix.socket")
 
@@ -968,7 +969,7 @@ func (d *Daemon) Init() error {
 		if shared.PathExists(localSocketPath) {
 			_, err := lxd.ConnectLXDUnix("", nil)
 			if err != nil {
-				shared.LogDebugf("Detected stale unix socket, deleting")
+				logger.Debugf("Detected stale unix socket, deleting")
 				// Connecting failed, so let's delete the socket and
 				// listen on it ourselves.
 				err = os.Remove(localSocketPath)
@@ -1020,10 +1021,10 @@ func (d *Daemon) Init() error {
 
 		tcpl, err := tls.Listen("tcp", listenAddr, d.tlsConfig)
 		if err != nil {
-			shared.LogError("cannot listen on https socket, skipping...", log.Ctx{"err": err})
+			logger.Error("cannot listen on https socket, skipping...", log.Ctx{"err": err})
 		} else {
 			if d.TCPSocket != nil {
-				shared.LogInfof("Replacing inherited TCP socket with configured one")
+				logger.Infof("Replacing inherited TCP socket with configured one")
 				d.TCPSocket.Socket.Close()
 			}
 			d.TCPSocket = &Socket{Socket: tcpl, CloseOnExit: true}
@@ -1031,14 +1032,14 @@ func (d *Daemon) Init() error {
 	}
 
 	// Bind the REST API
-	shared.LogInfof("REST API daemon:")
+	logger.Infof("REST API daemon:")
 	if d.UnixSocket != nil {
-		shared.LogInfo(" - binding Unix socket", log.Ctx{"socket": d.UnixSocket.Socket.Addr()})
+		logger.Info(" - binding Unix socket", log.Ctx{"socket": d.UnixSocket.Socket.Addr()})
 		d.tomb.Go(func() error { return http.Serve(d.UnixSocket.Socket, &lxdHttpServer{d.mux, d}) })
 	}
 
 	if d.TCPSocket != nil {
-		shared.LogInfo(" - binding TCP socket", log.Ctx{"socket": d.TCPSocket.Socket.Addr()})
+		logger.Info(" - binding TCP socket", log.Ctx{"socket": d.TCPSocket.Socket.Addr()})
 		d.tomb.Go(func() error { return http.Serve(d.TCPSocket.Socket, &lxdHttpServer{d.mux, d}) })
 	}
 
@@ -1119,7 +1120,7 @@ func (d *Daemon) Ready() error {
 func (d *Daemon) CheckTrustState(cert x509.Certificate) bool {
 	for k, v := range d.clientCerts {
 		if bytes.Compare(cert.Raw, v.Raw) == 0 {
-			shared.LogDebug("Found cert", log.Ctx{"k": k})
+			logger.Debug("Found cert", log.Ctx{"k": k})
 			return true
 		}
 	}
@@ -1155,42 +1156,42 @@ func (d *Daemon) Stop() error {
 	forceStop := false
 
 	d.tomb.Kill(errStop)
-	shared.LogInfof("Stopping REST API handler:")
+	logger.Infof("Stopping REST API handler:")
 	for _, socket := range []*Socket{d.TCPSocket, d.UnixSocket} {
 		if socket == nil {
 			continue
 		}
 
 		if socket.CloseOnExit {
-			shared.LogInfo(" - closing socket", log.Ctx{"socket": socket.Socket.Addr()})
+			logger.Info(" - closing socket", log.Ctx{"socket": socket.Socket.Addr()})
 			socket.Socket.Close()
 		} else {
-			shared.LogInfo(" - skipping socket-activated socket", log.Ctx{"socket": socket.Socket.Addr()})
+			logger.Info(" - skipping socket-activated socket", log.Ctx{"socket": socket.Socket.Addr()})
 			forceStop = true
 		}
 	}
 
-	shared.LogInfof("Stopping /dev/lxd handler")
+	logger.Infof("Stopping /dev/lxd handler")
 	d.devlxd.Close()
-	shared.LogInfof("Stopped /dev/lxd handler")
+	logger.Infof("Stopped /dev/lxd handler")
 
 	if n, err := d.numRunningContainers(); err != nil || n == 0 {
-		shared.LogInfof("Unmounting temporary filesystems")
+		logger.Infof("Unmounting temporary filesystems")
 
 		syscall.Unmount(shared.VarPath("devlxd"), syscall.MNT_DETACH)
 		syscall.Unmount(shared.VarPath("shmounts"), syscall.MNT_DETACH)
 
-		shared.LogInfof("Done unmounting temporary filesystems")
+		logger.Infof("Done unmounting temporary filesystems")
 	} else {
-		shared.LogDebugf("Not unmounting temporary filesystems (containers are still running)")
+		logger.Debugf("Not unmounting temporary filesystems (containers are still running)")
 	}
 
-	shared.LogInfof("Closing the database")
+	logger.Infof("Closing the database")
 	d.db.Close()
 
-	shared.LogInfof("Saving simplestreams cache")
+	logger.Infof("Saving simplestreams cache")
 	imageSaveStreamCache()
-	shared.LogInfof("Saved simplestreams cache")
+	logger.Infof("Saved simplestreams cache")
 
 	if d.MockMode || forceStop {
 		return nil
diff --git a/lxd/daemon_config.go b/lxd/daemon_config.go
index a8a487c..15c55a4 100644
--- a/lxd/daemon_config.go
+++ b/lxd/daemon_config.go
@@ -15,6 +15,7 @@ import (
 	log "gopkg.in/inconshreveable/log15.v2"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 var daemonConfigLock sync.Mutex
@@ -209,7 +210,7 @@ func daemonConfigInit(db *sql.DB) error {
 	for k, v := range dbValues {
 		_, ok := daemonConfig[k]
 		if !ok {
-			shared.LogError("Found invalid configuration key in database", log.Ctx{"key": k})
+			logger.Error("Found invalid configuration key in database", log.Ctx{"key": k})
 		}
 
 		daemonConfig[k].currentValue = v
diff --git a/lxd/daemon_images.go b/lxd/daemon_images.go
index b43d4d5..286b1a7 100644
--- a/lxd/daemon_images.go
+++ b/lxd/daemon_images.go
@@ -18,6 +18,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -153,7 +154,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 				entry = newEntry
 			} else if entry != nil {
 				// Failed to fetch entry but existing cache
-				shared.LogWarn("Unable to refresh cache, using stale entry", log.Ctx{"server": server})
+				logger.Warn("Unable to refresh cache, using stale entry", log.Ctx{"server": server})
 				entry.expiry = time.Now().Add(time.Hour)
 			} else {
 				// Failed to fetch entry and nothing in cache
@@ -162,7 +163,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 			}
 		} else {
 			// use the existing entry
-			shared.LogDebug("Using SimpleStreams cache entry", log.Ctx{"server": server, "expiry": entry.expiry})
+			logger.Debug("Using SimpleStreams cache entry", log.Ctx{"server": server, "expiry": entry.expiry})
 			remote = entry.remote
 		}
 		imageStreamCacheLock.Unlock()
@@ -222,7 +223,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 	// Check if the image already exists (partial hash match)
 	_, imgInfo, err := dbImageGet(d.db, fp, false, true)
 	if err == nil {
-		shared.LogDebug("Image already exists in the db", log.Ctx{"image": fp})
+		logger.Debug("Image already exists in the db", log.Ctx{"image": fp})
 		info = imgInfo
 
 		// If not requested in a particular pool, we're done.
@@ -243,20 +244,20 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		}
 
 		if shared.Int64InSlice(poolID, poolIDs) {
-			shared.LogDebugf("Image already exists on storage pool \"%s\".", storagePool)
+			logger.Debugf("Image already exists on storage pool \"%s\".", storagePool)
 			return info, nil
 		}
 
 		// Import the image in the pool
-		shared.LogDebugf("Image does not exist on storage pool \"%s\".", storagePool)
+		logger.Debugf("Image does not exist on storage pool \"%s\".", storagePool)
 
 		err = imageCreateInPool(d, info, storagePool)
 		if err != nil {
-			shared.LogDebugf("Failed to create image on storage pool \"%s\": %s.", storagePool, err)
+			logger.Debugf("Failed to create image on storage pool \"%s\": %s.", storagePool, err)
 			return nil, err
 		}
 
-		shared.LogDebugf("Created image on storage pool \"%s\".", storagePool)
+		logger.Debugf("Created image on storage pool \"%s\".", storagePool)
 		return info, nil
 	}
 
@@ -266,7 +267,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		// We are already downloading the image
 		imagesDownloadingLock.Unlock()
 
-		shared.LogDebug(
+		logger.Debug(
 			"Already downloading the image, waiting for it to succeed",
 			log.Ctx{"image": fp})
 
@@ -277,7 +278,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		_, imgInfo, err := dbImageGet(d.db, fp, false, true)
 		if err != nil {
 			// Other download failed, lets try again
-			shared.LogError("Other image download didn't succeed", log.Ctx{"image": fp})
+			logger.Error("Other image download didn't succeed", log.Ctx{"image": fp})
 		} else {
 			// Other download succeeded, we're done
 			return imgInfo, nil
@@ -304,7 +305,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 	} else {
 		ctxMap = log.Ctx{"trigger": op.url, "image": fp, "operation": op.id, "alias": alias, "server": server}
 	}
-	shared.LogInfo("Downloading image", ctxMap)
+	logger.Info("Downloading image", ctxMap)
 
 	// Cleanup any leftover from a past attempt
 	destDir := shared.VarPath("images")
@@ -498,6 +499,6 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		}
 	}
 
-	shared.LogInfo("Image downloaded", ctxMap)
+	logger.Info("Image downloaded", ctxMap)
 	return info, nil
 }
diff --git a/lxd/db.go b/lxd/db.go
index 74ddc00..291fa60 100644
--- a/lxd/db.go
+++ b/lxd/db.go
@@ -7,7 +7,7 @@ import (
 
 	"github.com/mattn/go-sqlite3"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 var (
@@ -334,14 +334,14 @@ func dbBegin(db *sql.DB) (*sql.Tx, error) {
 			return tx, nil
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("DbBegin: error %q", err)
+			logger.Debugf("DbBegin: error %q", err)
 			return nil, err
 		}
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DbBegin: DB still locked")
-	shared.PrintStack()
+	logger.Debugf("DbBegin: DB still locked")
+	logger.PrintStack()
 	return nil, fmt.Errorf("DB is locked")
 }
 
@@ -352,14 +352,14 @@ func txCommit(tx *sql.Tx) error {
 			return nil
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("Txcommit: error %q", err)
+			logger.Debugf("Txcommit: error %q", err)
 			return err
 		}
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("Txcommit: db still locked")
-	shared.PrintStack()
+	logger.Debugf("Txcommit: db still locked")
+	logger.PrintStack()
 	return fmt.Errorf("DB is locked")
 }
 
@@ -378,8 +378,8 @@ func dbQueryRowScan(db *sql.DB, q string, args []interface{}, outargs []interfac
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DbQueryRowScan: query %q args %q, DB still locked", q, args)
-	shared.PrintStack()
+	logger.Debugf("DbQueryRowScan: query %q args %q, DB still locked", q, args)
+	logger.PrintStack()
 	return fmt.Errorf("DB is locked")
 }
 
@@ -390,14 +390,14 @@ func dbQuery(db *sql.DB, q string, args ...interface{}) (*sql.Rows, error) {
 			return result, nil
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("DbQuery: query %q error %q", q, err)
+			logger.Debugf("DbQuery: query %q error %q", q, err)
 			return nil, err
 		}
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DbQuery: query %q args %q, DB still locked", q, args)
-	shared.PrintStack()
+	logger.Debugf("DbQuery: query %q args %q, DB still locked", q, args)
+	logger.PrintStack()
 	return nil, fmt.Errorf("DB is locked")
 }
 
@@ -470,14 +470,14 @@ func dbQueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{
 			return result, nil
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("DbQuery: query %q error %q", q, err)
+			logger.Debugf("DbQuery: query %q error %q", q, err)
 			return nil, err
 		}
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DbQueryscan: query %q inargs %q, DB still locked", q, inargs)
-	shared.PrintStack()
+	logger.Debugf("DbQueryscan: query %q inargs %q, DB still locked", q, inargs)
+	logger.PrintStack()
 	return nil, fmt.Errorf("DB is locked")
 }
 
@@ -488,13 +488,13 @@ func dbExec(db *sql.DB, q string, args ...interface{}) (sql.Result, error) {
 			return result, nil
 		}
 		if !isDbLockedError(err) {
-			shared.LogDebugf("DbExec: query %q error %q", q, err)
+			logger.Debugf("DbExec: query %q error %q", q, err)
 			return nil, err
 		}
 		time.Sleep(30 * time.Millisecond)
 	}
 
-	shared.LogDebugf("DbExec: query %q args %q, DB still locked", q, args)
-	shared.PrintStack()
+	logger.Debugf("DbExec: query %q args %q, DB still locked", q, args)
+	logger.PrintStack()
 	return nil, fmt.Errorf("DB is locked")
 }
diff --git a/lxd/db_containers.go b/lxd/db_containers.go
index f1a8363..58255da 100644
--- a/lxd/db_containers.go
+++ b/lxd/db_containers.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -204,7 +205,7 @@ func dbContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error
 	for k, v := range config {
 		_, err := stmt.Exec(id, k, v)
 		if err != nil {
-			shared.LogDebugf("Error adding configuration item %s = %s to container %d",
+			logger.Debugf("Error adding configuration item %s = %s to container %d",
 				k, v, id)
 			return err
 		}
@@ -249,7 +250,7 @@ func dbContainerProfilesInsert(tx *sql.Tx, id int, profiles []string) error {
 	for _, p := range profiles {
 		_, err = stmt.Exec(id, p, applyOrder)
 		if err != nil {
-			shared.LogDebugf("Error adding profile %s to container: %s",
+			logger.Debugf("Error adding profile %s to container: %s",
 				p, err)
 			return err
 		}
@@ -381,7 +382,7 @@ func dbContainerRename(db *sql.DB, oldName string, newName string) error {
 	}
 	defer stmt.Close()
 
-	shared.LogDebug(
+	logger.Debug(
 		"Calling SQL Query",
 		log.Ctx{
 			"query":   "UPDATE containers SET name = ? WHERE name = ?",
diff --git a/lxd/db_test.go b/lxd/db_test.go
index e61d187..c771b07 100644
--- a/lxd/db_test.go
+++ b/lxd/db_test.go
@@ -30,9 +30,9 @@ const DB_FIXTURES string = `
 // This Helper will initialize a test in-memory DB.
 func createTestDb(t *testing.T) (db *sql.DB) {
 	// Setup logging if main() hasn't been called/when testing
-	if shared.Log == nil {
+	if logger.Log == nil {
 		var err error
-		shared.Log, err = logging.GetLogger("", "", true, true, nil)
+		logger.Log, err = logging.GetLogger("", "", true, true, nil)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/lxd/db_update.go b/lxd/db_update.go
index 9d274a0..f40208b 100644
--- a/lxd/db_update.go
+++ b/lxd/db_update.go
@@ -11,6 +11,7 @@ import (
 	"syscall"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -78,7 +79,7 @@ type dbUpdate struct {
 func (u *dbUpdate) apply(currentVersion int, d *Daemon) error {
 	// Get the current schema version
 
-	shared.LogDebugf("Updating DB schema from %d to %d", currentVersion, u.version)
+	logger.Debugf("Updating DB schema from %d to %d", currentVersion, u.version)
 
 	err := u.run(currentVersion, u.version, d)
 	if err != nil {
@@ -103,7 +104,7 @@ func dbUpdatesApplyAll(d *Daemon) error {
 		}
 
 		if !d.MockMode && !backup {
-			shared.LogInfof("Updating the LXD database schema. Backup made as \"lxd.db.bak\"")
+			logger.Infof("Updating the LXD database schema. Backup made as \"lxd.db.bak\"")
 			err := shared.FileCopy(shared.VarPath("lxd.db"), shared.VarPath("lxd.db.bak"))
 			if err != nil {
 				return err
@@ -371,7 +372,7 @@ func dbUpdateFromV18(currentVersion int, version int, d *Daemon) error {
 		// Deal with completely broken values
 		_, err = shared.ParseByteSizeString(value)
 		if err != nil {
-			shared.LogDebugf("Invalid container memory limit, id=%d value=%s, removing.", id, value)
+			logger.Debugf("Invalid container memory limit, id=%d value=%s, removing.", id, value)
 			_, err = d.db.Exec("DELETE FROM containers_config WHERE id=?;", id)
 			if err != nil {
 				return err
@@ -408,7 +409,7 @@ func dbUpdateFromV18(currentVersion int, version int, d *Daemon) error {
 		// Deal with completely broken values
 		_, err = shared.ParseByteSizeString(value)
 		if err != nil {
-			shared.LogDebugf("Invalid profile memory limit, id=%d value=%s, removing.", id, value)
+			logger.Debugf("Invalid profile memory limit, id=%d value=%s, removing.", id, value)
 			_, err = d.db.Exec("DELETE FROM profiles_config WHERE id=?;", id)
 			if err != nil {
 				return err
@@ -474,11 +475,11 @@ func dbUpdateFromV15(currentVersion int, version int, d *Daemon) error {
 		newLVName = strings.Replace(newLVName, shared.SnapshotDelimiter, "-", -1)
 
 		if cName == newLVName {
-			shared.LogDebug("No need to rename, skipping", log.Ctx{"cName": cName, "newLVName": newLVName})
+			logger.Debug("No need to rename, skipping", log.Ctx{"cName": cName, "newLVName": newLVName})
 			continue
 		}
 
-		shared.LogDebug("About to rename cName in lv upgrade", log.Ctx{"lvLinkPath": lvLinkPath, "cName": cName, "newLVName": newLVName})
+		logger.Debug("About to rename cName in lv upgrade", log.Ctx{"lvLinkPath": lvLinkPath, "cName": cName, "newLVName": newLVName})
 
 		output, err := shared.RunCommand("lvrename", vgName, cName, newLVName)
 		if err != nil {
@@ -564,7 +565,7 @@ func dbUpdateFromV11(currentVersion int, version int, d *Daemon) error {
 		oldPath := shared.VarPath("containers", snappieces[0], "snapshots", snappieces[1])
 		newPath := shared.VarPath("snapshots", snappieces[0], snappieces[1])
 		if shared.PathExists(oldPath) && !shared.PathExists(newPath) {
-			shared.LogInfo(
+			logger.Info(
 				"Moving snapshot",
 				log.Ctx{
 					"snapshot": cName,
@@ -577,7 +578,7 @@ func dbUpdateFromV11(currentVersion int, version int, d *Daemon) error {
 			// snapshots/<container>/<snap0>
 			output, err := storageRsyncCopy(oldPath, newPath)
 			if err != nil {
-				shared.LogError(
+				logger.Error(
 					"Failed rsync snapshot",
 					log.Ctx{
 						"snapshot": cName,
@@ -589,7 +590,7 @@ func dbUpdateFromV11(currentVersion int, version int, d *Daemon) error {
 
 			// Remove containers/<container>/snapshots/<snap0>
 			if err := os.RemoveAll(oldPath); err != nil {
-				shared.LogError(
+				logger.Error(
 					"Failed to remove the old snapshot path",
 					log.Ctx{
 						"snapshot": cName,
@@ -632,7 +633,7 @@ func dbUpdateFromV10(currentVersion int, version int, d *Daemon) error {
 			return err
 		}
 
-		shared.LogDebugf("Restarting all the containers following directory rename")
+		logger.Debugf("Restarting all the containers following directory rename")
 		containersShutdown(d)
 		containersRestart(d)
 	}
diff --git a/lxd/debug.go b/lxd/debug.go
index f1a0fd7..d255e34 100644
--- a/lxd/debug.go
+++ b/lxd/debug.go
@@ -6,13 +6,13 @@ import (
 	"runtime/pprof"
 	"syscall"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func doMemDump(memProfile string) {
 	f, err := os.Create(memProfile)
 	if err != nil {
-		shared.LogDebugf("Error opening memory profile file '%s': %s", err)
+		logger.Debugf("Error opening memory profile file '%s': %s", err)
 		return
 	}
 	pprof.WriteHeapProfile(f)
@@ -24,7 +24,7 @@ func memProfiler(memProfile string) {
 	signal.Notify(ch, syscall.SIGUSR1)
 	for {
 		sig := <-ch
-		shared.LogDebugf("Received '%s signal', dumping memory.", sig)
+		logger.Debugf("Received '%s signal', dumping memory.", sig)
 		doMemDump(memProfile)
 	}
 }
diff --git a/lxd/devices.go b/lxd/devices.go
index dff4493..b15eede 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -20,6 +20,7 @@ import (
 	_ "github.com/mattn/go-sqlite3"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -440,7 +441,7 @@ func deviceNetlinkListener() (chan []string, chan []string, chan usbDevice, erro
 					devname,
 				)
 				if err != nil {
-					shared.LogError("error reading usb device", log.Ctx{"err": err, "path": props["PHYSDEVPATH"]})
+					logger.Error("error reading usb device", log.Ctx{"err": err, "path": props["PHYSDEVPATH"]})
 					continue
 				}
 
@@ -508,24 +509,24 @@ func deviceTaskBalance(d *Daemon) {
 		// Older kernel - use cpuset.cpus
 		effectiveCpus, err = cGroupGet("cpuset", "/", "cpuset.cpus")
 		if err != nil {
-			shared.LogErrorf("Error reading host's cpuset.cpus")
+			logger.Errorf("Error reading host's cpuset.cpus")
 			return
 		}
 	}
 	err = cGroupSet("cpuset", "/lxc", "cpuset.cpus", effectiveCpus)
 	if err != nil && shared.PathExists("/sys/fs/cgroup/cpuset/lxc") {
-		shared.LogWarn("Error setting lxd's cpuset.cpus", log.Ctx{"err": err})
+		logger.Warn("Error setting lxd's cpuset.cpus", log.Ctx{"err": err})
 	}
 	cpus, err := parseCpuset(effectiveCpus)
 	if err != nil {
-		shared.LogError("Error parsing host's cpu set", log.Ctx{"cpuset": effectiveCpus, "err": err})
+		logger.Error("Error parsing host's cpu set", log.Ctx{"cpuset": effectiveCpus, "err": err})
 		return
 	}
 
 	// Iterate through the containers
 	containers, err := dbContainersList(d.db, cTypeRegular)
 	if err != nil {
-		shared.LogError("problem loading containers list", log.Ctx{"err": err})
+		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
 	}
 	fixedContainers := map[int][]container{}
@@ -589,7 +590,7 @@ func deviceTaskBalance(d *Daemon) {
 	for cpu, ctns := range fixedContainers {
 		c, ok := usage[cpu]
 		if !ok {
-			shared.LogErrorf("Internal error: container using unavailable cpu")
+			logger.Errorf("Internal error: container using unavailable cpu")
 			continue
 		}
 		id := c.strId
@@ -638,7 +639,7 @@ func deviceTaskBalance(d *Daemon) {
 		sort.Strings(set)
 		err := ctn.CGroupSet("cpuset.cpus", strings.Join(set, ","))
 		if err != nil {
-			shared.LogError("balance: Unable to set cpuset", log.Ctx{"name": ctn.Name(), "err": err, "value": strings.Join(set, ",")})
+			logger.Error("balance: Unable to set cpuset", log.Ctx{"name": ctn.Name(), "err": err, "value": strings.Join(set, ",")})
 		}
 	}
 }
@@ -682,7 +683,7 @@ func deviceNetworkPriority(d *Daemon, netif string) {
 func deviceUSBEvent(d *Daemon, usb usbDevice) {
 	containers, err := dbContainersList(d.db, cTypeRegular)
 	if err != nil {
-		shared.LogError("problem loading containers list", log.Ctx{"err": err})
+		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
 	}
 
@@ -694,7 +695,7 @@ func deviceUSBEvent(d *Daemon, usb usbDevice) {
 
 		c, ok := containerIf.(*containerLXC)
 		if !ok {
-			shared.LogErrorf("got device event on non-LXC container?")
+			logger.Errorf("got device event on non-LXC container?")
 			return
 		}
 
@@ -716,17 +717,17 @@ func deviceUSBEvent(d *Daemon, usb usbDevice) {
 			if usb.action == "add" {
 				err := c.insertUnixDeviceNum(m, usb.major, usb.minor, usb.path)
 				if err != nil {
-					shared.LogError("failed to create usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
+					logger.Error("failed to create usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
 					return
 				}
 			} else if usb.action == "remove" {
 				err := c.removeUnixDeviceNum(m, usb.major, usb.minor, usb.path)
 				if err != nil {
-					shared.LogError("failed to remove usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
+					logger.Error("failed to remove usb device", log.Ctx{"err": err, "usb": usb, "container": c.Name()})
 					return
 				}
 			} else {
-				shared.LogError("unknown action for usb device", log.Ctx{"usb": usb})
+				logger.Error("unknown action for usb device", log.Ctx{"usb": usb})
 				continue
 			}
 		}
@@ -736,7 +737,7 @@ func deviceUSBEvent(d *Daemon, usb usbDevice) {
 func deviceEventListener(d *Daemon) {
 	chNetlinkCPU, chNetlinkNetwork, chUSB, err := deviceNetlinkListener()
 	if err != nil {
-		shared.LogErrorf("scheduler: couldn't setup netlink listener")
+		logger.Errorf("scheduler: couldn't setup netlink listener")
 		return
 	}
 
@@ -744,7 +745,7 @@ func deviceEventListener(d *Daemon) {
 		select {
 		case e := <-chNetlinkCPU:
 			if len(e) != 2 {
-				shared.LogErrorf("Scheduler: received an invalid cpu hotplug event")
+				logger.Errorf("Scheduler: received an invalid cpu hotplug event")
 				continue
 			}
 
@@ -752,11 +753,11 @@ func deviceEventListener(d *Daemon) {
 				continue
 			}
 
-			shared.LogDebugf("Scheduler: cpu: %s is now %s: re-balancing", e[0], e[1])
+			logger.Debugf("Scheduler: cpu: %s is now %s: re-balancing", e[0], e[1])
 			deviceTaskBalance(d)
 		case e := <-chNetlinkNetwork:
 			if len(e) != 2 {
-				shared.LogErrorf("Scheduler: received an invalid network hotplug event")
+				logger.Errorf("Scheduler: received an invalid network hotplug event")
 				continue
 			}
 
@@ -764,14 +765,14 @@ func deviceEventListener(d *Daemon) {
 				continue
 			}
 
-			shared.LogDebugf("Scheduler: network: %s has been added: updating network priorities", e[0])
+			logger.Debugf("Scheduler: network: %s has been added: updating network priorities", e[0])
 			deviceNetworkPriority(d, e[0])
 			networkAutoAttach(d, e[0])
 		case e := <-chUSB:
 			deviceUSBEvent(d, e)
 		case e := <-deviceSchedRebalance:
 			if len(e) != 3 {
-				shared.LogErrorf("Scheduler: received an invalid rebalance event")
+				logger.Errorf("Scheduler: received an invalid rebalance event")
 				continue
 			}
 
@@ -779,7 +780,7 @@ func deviceEventListener(d *Daemon) {
 				continue
 			}
 
-			shared.LogDebugf("Scheduler: %s %s %s: re-balancing", e[0], e[1], e[2])
+			logger.Debugf("Scheduler: %s %s %s: re-balancing", e[0], e[1], e[2])
 			deviceTaskBalance(d)
 		}
 	}
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index 73597e7..c2ece9d 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -16,6 +16,7 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -218,7 +219,7 @@ func (m *ConnPidMapper) ConnStateHandler(conn net.Conn, state http.ConnState) {
 	case http.StateNew:
 		cred, err := getCred(unixConn)
 		if err != nil {
-			shared.LogDebugf("Error getting ucred for conn %s", err)
+			logger.Debugf("Error getting ucred for conn %s", err)
 		} else {
 			m.m[unixConn] = cred
 		}
@@ -239,7 +240,7 @@ func (m *ConnPidMapper) ConnStateHandler(conn net.Conn, state http.ConnState) {
 	case http.StateClosed:
 		delete(m.m, unixConn)
 	default:
-		shared.LogDebugf("Unknown state for connection %s", state)
+		logger.Debugf("Unknown state for connection %s", state)
 	}
 }
 
diff --git a/lxd/events.go b/lxd/events.go
index 5778ae9..df3bdc6 100644
--- a/lxd/events.go
+++ b/lxd/events.go
@@ -13,6 +13,7 @@ import (
 	log "gopkg.in/inconshreveable/log15.v2"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type eventsHandler struct {
@@ -87,7 +88,7 @@ func eventsSocket(r *http.Request, w http.ResponseWriter) error {
 	eventListeners[listener.id] = &listener
 	eventsLock.Unlock()
 
-	shared.LogDebugf("New events listener: %s", listener.id)
+	logger.Debugf("New events listener: %s", listener.id)
 
 	<-listener.active
 
@@ -96,7 +97,7 @@ func eventsSocket(r *http.Request, w http.ResponseWriter) error {
 	eventsLock.Unlock()
 
 	listener.connection.Close()
-	shared.LogDebugf("Disconnected events listener: %s", listener.id)
+	logger.Debugf("Disconnected events listener: %s", listener.id)
 
 	return nil
 }
diff --git a/lxd/images.go b/lxd/images.go
index 7bbcba9..01c44f6 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
 	"github.com/lxc/lxd/shared/osarch"
 	"github.com/lxc/lxd/shared/version"
@@ -137,8 +138,8 @@ func unpack(d *Daemon, file string, path string, sType storageType) error {
 		}
 
 		co := output
-		shared.LogDebugf("Unpacking failed")
-		shared.LogDebugf(co)
+		logger.Debugf("Unpacking failed")
+		logger.Debugf(co)
 
 		// Truncate the output to a single line for inclusion in the error
 		// message.  The first line isn't guaranteed to pinpoint the issue,
@@ -435,7 +436,7 @@ func imgPostURLInfo(d *Daemon, req api.ImagesPost, op *operation) (*api.Image, e
 func getImgPostInfo(d *Daemon, r *http.Request, builddir string, post *os.File) (*api.Image, error) {
 	info := api.Image{}
 	var imageMeta *imageMetadata
-	logger := logging.AddContext(shared.Log, log.Ctx{"function": "getImgPostInfo"})
+	logger := logging.AddContext(logger.Log, log.Ctx{"function": "getImgPostInfo"})
 
 	public, _ := strconv.Atoi(r.Header.Get("X-LXD-public"))
 	info.Public = public == 1
@@ -668,7 +669,7 @@ func imagesPost(d *Daemon, r *http.Request) Response {
 		}
 
 		if err := os.RemoveAll(path); err != nil {
-			shared.LogDebugf("Error deleting temporary directory \"%s\": %s", path, err)
+			logger.Debugf("Error deleting temporary directory \"%s\": %s", path, err)
 		}
 	}
 
@@ -863,18 +864,18 @@ func imagesGet(d *Daemon, r *http.Request) Response {
 var imagesCmd = Command{name: "images", post: imagesPost, untrustedGet: true, get: imagesGet}
 
 func autoUpdateImages(d *Daemon) {
-	shared.LogInfof("Updating images")
+	logger.Infof("Updating images")
 
 	images, err := dbImagesGet(d.db, false)
 	if err != nil {
-		shared.LogError("Unable to retrieve the list of images", log.Ctx{"err": err})
+		logger.Error("Unable to retrieve the list of images", log.Ctx{"err": err})
 		return
 	}
 
 	for _, fp := range images {
 		id, info, err := dbImageGet(d.db, fp, false, true)
 		if err != nil {
-			shared.LogError("Error loading image", log.Ctx{"err": err, "fp": fp})
+			logger.Error("Error loading image", log.Ctx{"err": err, "fp": fp})
 			continue
 		}
 
@@ -905,44 +906,44 @@ func autoUpdateImages(d *Daemon) {
 			poolNames = append(poolNames, "")
 		}
 
-		shared.LogDebug("Processing image", log.Ctx{"fp": fp, "server": source.Server, "protocol": source.Protocol, "alias": source.Alias})
+		logger.Debug("Processing image", log.Ctx{"fp": fp, "server": source.Server, "protocol": source.Protocol, "alias": source.Alias})
 
 		// Update the image on each pool where it currently exists.
 		hash := fp
 		for _, poolName := range poolNames {
 			newInfo, err := d.ImageDownload(nil, source.Server, source.Protocol, "", "", source.Alias, false, true, poolName)
 			if err != nil {
-				shared.LogError("Failed to update the image", log.Ctx{"err": err, "fp": fp})
+				logger.Error("Failed to update the image", log.Ctx{"err": err, "fp": fp})
 				continue
 			}
 
 			hash = newInfo.Fingerprint
 			if hash == fp {
-				shared.LogDebug("Already up to date", log.Ctx{"fp": fp})
+				logger.Debug("Already up to date", log.Ctx{"fp": fp})
 				continue
 			}
 
 			newId, _, err := dbImageGet(d.db, hash, false, true)
 			if err != nil {
-				shared.LogError("Error loading image", log.Ctx{"err": err, "fp": hash})
+				logger.Error("Error loading image", log.Ctx{"err": err, "fp": hash})
 				continue
 			}
 
 			err = dbImageLastAccessUpdate(d.db, hash, info.LastUsedAt)
 			if err != nil {
-				shared.LogError("Error setting last use date", log.Ctx{"err": err, "fp": hash})
+				logger.Error("Error setting last use date", log.Ctx{"err": err, "fp": hash})
 				continue
 			}
 
 			err = dbImageAliasesMove(d.db, id, newId)
 			if err != nil {
-				shared.LogError("Error moving aliases", log.Ctx{"err": err, "fp": hash})
+				logger.Error("Error moving aliases", log.Ctx{"err": err, "fp": hash})
 				continue
 			}
 
 			err = doDeleteImageFromPool(d, fp, poolName)
 			if err != nil {
-				shared.LogError("Error deleting image", log.Ctx{"err": err, "fp": fp})
+				logger.Error("Error deleting image", log.Ctx{"err": err, "fp": fp})
 			}
 		}
 
@@ -956,7 +957,7 @@ func autoUpdateImages(d *Daemon) {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
@@ -965,27 +966,27 @@ func autoUpdateImages(d *Daemon) {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
 		// Remove the database entry for the image.
 		if err = dbImageDelete(d.db, id); err != nil {
-			shared.LogDebugf("Error deleting image from database %s: %s", fname, err)
+			logger.Debugf("Error deleting image from database %s: %s", fname, err)
 		}
 	}
 
-	shared.LogInfof("Done updating images")
+	logger.Infof("Done updating images")
 }
 
 func pruneExpiredImages(d *Daemon) {
-	shared.LogInfof("Pruning expired images")
+	logger.Infof("Pruning expired images")
 
 	// Get the list of expired images.
 	expiry := daemonConfig["images.remote_cache_expiry"].GetInt64()
 	images, err := dbImagesGetExpired(d.db, expiry)
 	if err != nil {
-		shared.LogError("Unable to retrieve the list of expired images", log.Ctx{"err": err})
+		logger.Error("Unable to retrieve the list of expired images", log.Ctx{"err": err})
 		return
 	}
 
@@ -1007,7 +1008,7 @@ func pruneExpiredImages(d *Daemon) {
 		for _, pool := range poolNames {
 			err := doDeleteImageFromPool(d, fp, pool)
 			if err != nil {
-				shared.LogDebugf("Error deleting image %s from storage pool %: %s", fp, pool, err)
+				logger.Debugf("Error deleting image %s from storage pool %: %s", fp, pool, err)
 				continue
 			}
 		}
@@ -1017,7 +1018,7 @@ func pruneExpiredImages(d *Daemon) {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
@@ -1026,22 +1027,22 @@ func pruneExpiredImages(d *Daemon) {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
 		imgID, _, err := dbImageGet(d.db, fp, false, false)
 		if err != nil {
-			shared.LogDebugf("Error retrieving image info %s: %s", fp, err)
+			logger.Debugf("Error retrieving image info %s: %s", fp, err)
 		}
 
 		// Remove the database entry for the image.
 		if err = dbImageDelete(d.db, imgID); err != nil {
-			shared.LogDebugf("Error deleting image %s from database: %s", fp, err)
+			logger.Debugf("Error deleting image %s from database: %s", fp, err)
 		}
 	}
 
-	shared.LogInfof("Done pruning expired images")
+	logger.Infof("Done pruning expired images")
 }
 
 func doDeleteImageFromPool(d *Daemon, fingerprint string, storagePool string) error {
@@ -1093,7 +1094,7 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
@@ -1102,7 +1103,7 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 		if shared.PathExists(fname) {
 			err = os.Remove(fname)
 			if err != nil {
-				shared.LogDebugf("Error deleting image file %s: %s", fname, err)
+				logger.Debugf("Error deleting image file %s: %s", fname, err)
 			}
 		}
 
diff --git a/lxd/main.go b/lxd/main.go
index 733b2d9..3258f3d 100644
--- a/lxd/main.go
+++ b/lxd/main.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/gnuflag"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
 	"github.com/lxc/lxd/shared/version"
 )
@@ -186,7 +187,7 @@ func run() error {
 
 	handler := eventsHandler{}
 	var err error
-	shared.Log, err = logging.GetLogger(syslog, *argLogfile, *argVerbose, *argDebug, handler)
+	logger.Log, err = logging.GetLogger(syslog, *argLogfile, *argVerbose, *argDebug, handler)
 	if err != nil {
 		fmt.Printf("%s", err)
 		return nil
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index da6de2b..753d25d 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func cmdActivateIfNeeded() error {
@@ -20,7 +21,7 @@ func cmdActivateIfNeeded() error {
 	}
 
 	if !shared.PathExists(shared.VarPath("lxd.db")) {
-		shared.LogDebugf("No DB, so no need to start the daemon now.")
+		logger.Debugf("No DB, so no need to start the daemon now.")
 		return nil
 	}
 
@@ -38,7 +39,7 @@ func cmdActivateIfNeeded() error {
 	// Look for network socket
 	value := daemonConfig["core.https_address"].Get()
 	if value != "" {
-		shared.LogDebugf("Daemon has core.https_address set, activating...")
+		logger.Debugf("Daemon has core.https_address set, activating...")
 		_, err := lxd.ConnectLXDUnix("", nil)
 		return err
 	}
@@ -66,18 +67,18 @@ func cmdActivateIfNeeded() error {
 		autoStart := config["boot.autostart"]
 
 		if c.IsRunning() {
-			shared.LogDebugf("Daemon has running containers, activating...")
+			logger.Debugf("Daemon has running containers, activating...")
 			_, err := lxd.ConnectLXDUnix("", nil)
 			return err
 		}
 
 		if lastState == "RUNNING" || lastState == "Running" || shared.IsTrue(autoStart) {
-			shared.LogDebugf("Daemon has auto-started containers, activating...")
+			logger.Debugf("Daemon has auto-started containers, activating...")
 			_, err := lxd.ConnectLXDUnix("", nil)
 			return err
 		}
 	}
 
-	shared.LogDebugf("No need to start the daemon now.")
+	logger.Debugf("No need to start the daemon now.")
 	return nil
 }
diff --git a/lxd/main_daemon.go b/lxd/main_daemon.go
index 2560e9b..0d7851f 100644
--- a/lxd/main_daemon.go
+++ b/lxd/main_daemon.go
@@ -11,6 +11,7 @@ import (
 	"time"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func cmdDaemon() error {
@@ -45,7 +46,7 @@ func cmdDaemon() error {
 		go func() {
 			for {
 				time.Sleep(time.Duration(*argPrintGoroutinesEvery) * time.Second)
-				shared.PrintStack()
+				logger.PrintStack()
 			}
 		}()
 	}
@@ -70,7 +71,7 @@ func cmdDaemon() error {
 		signal.Notify(ch, syscall.SIGPWR)
 		sig := <-ch
 
-		shared.LogInfof("Received '%s signal', shutting down containers.", sig)
+		logger.Infof("Received '%s signal', shutting down containers.", sig)
 
 		containersShutdown(d)
 
@@ -81,7 +82,7 @@ func cmdDaemon() error {
 	go func() {
 		<-d.shutdownChan
 
-		shared.LogInfof("Asked to shutdown by API, shutting down containers.")
+		logger.Infof("Asked to shutdown by API, shutting down containers.")
 
 		containersShutdown(d)
 
@@ -96,7 +97,7 @@ func cmdDaemon() error {
 		signal.Notify(ch, syscall.SIGTERM)
 		sig := <-ch
 
-		shared.LogInfof("Received '%s signal', exiting.", sig)
+		logger.Infof("Received '%s signal', exiting.", sig)
 		ret = d.Stop()
 		wg.Done()
 	}()
diff --git a/lxd/main_init.go b/lxd/main_init.go
index a51e893..519f09b 100644
--- a/lxd/main_init.go
+++ b/lxd/main_init.go
@@ -14,6 +14,7 @@ import (
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func cmdInit() error {
@@ -520,7 +521,7 @@ they otherwise would.
 						if err != nil {
 							return err
 						}
-						shared.LogDebugf("Set pool property of existing root disk device \"%s\" in profile \"default\" to \"%s\".", storagePool)
+						logger.Debugf("Set pool property of existing root disk device \"%s\" in profile \"default\" to \"%s\".", storagePool)
 
 						break
 					}
@@ -545,7 +546,7 @@ they otherwise would.
 			}
 
 			if !defaultProfileExists {
-				shared.LogWarnf("Did not find profile \"default\" so no default storage pool will be set. Manual intervention needed.")
+				logger.Warnf("Did not find profile \"default\" so no default storage pool will be set. Manual intervention needed.")
 			}
 		}
 	}
diff --git a/lxd/migrate.go b/lxd/migrate.go
index 1e1e43b..77ea9d3 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -21,6 +21,7 @@ import (
 	"gopkg.in/lxc/go-lxc.v2"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type migrationFields struct {
@@ -137,7 +138,7 @@ func (c *migrationFields) controlChannel() <-chan MigrationControl {
 		msg := MigrationControl{}
 		err := c.recv(&msg)
 		if err != nil {
-			shared.LogDebugf("Got error reading migration control socket %s", err)
+			logger.Debugf("Got error reading migration control socket %s", err)
 			close(ch)
 			return
 		}
@@ -497,7 +498,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 				return abort(err)
 			/* the dump finished, let's continue on to the restore */
 			case <-dumpDone:
-				shared.LogDebugf("Dump finished, continuing with restore...")
+				logger.Debugf("Dump finished, continuing with restore...")
 			}
 		} else {
 			defer os.RemoveAll(checkpointDir)
@@ -538,7 +539,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 		restoreSuccess <- *msg.Success
 		err := <-dumpSuccess
 		if err != nil {
-			shared.LogErrorf("dump failed after successful restore?: %q", err)
+			logger.Errorf("dump failed after successful restore?: %q", err)
 		}
 	}
 
@@ -908,7 +909,7 @@ func (c *migrationSink) Do(migrateOp *operation) error {
 				// The source can only tell us it failed (e.g. if
 				// checkpointing failed). We have to tell the source
 				// whether or not the restore was successful.
-				shared.LogDebugf("Unknown message %v from source", msg)
+				logger.Debugf("Unknown message %v from source", msg)
 			}
 		}
 	}
diff --git a/lxd/networks.go b/lxd/networks.go
index 3ea207b..5e2e1b6 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -16,6 +16,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -411,7 +412,7 @@ func networkStartup(d *Daemon) error {
 		err = n.Start()
 		if err != nil {
 			// Don't cause LXD to fail to start entirely on network bring up failure
-			shared.LogError("Failed to bring up network", log.Ctx{"err": err, "name": name})
+			logger.Error("Failed to bring up network", log.Ctx{"err": err, "name": name})
 		}
 	}
 
diff --git a/lxd/operations.go b/lxd/operations.go
index 517652b..161ff03 100644
--- a/lxd/operations.go
+++ b/lxd/operations.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -118,7 +119,7 @@ func (op *operation) Run() (chan error, error) {
 				op.done()
 				chanRun <- err
 
-				shared.LogDebugf("Failure for %s operation: %s: %s", op.class.String(), op.id, err)
+				logger.Debugf("Failure for %s operation: %s: %s", op.class.String(), op.id, err)
 
 				_, md, _ := op.Render()
 				eventSend("operation", md)
@@ -132,7 +133,7 @@ func (op *operation) Run() (chan error, error) {
 			chanRun <- nil
 
 			op.lock.Lock()
-			shared.LogDebugf("Success for %s operation: %s", op.class.String(), op.id)
+			logger.Debugf("Success for %s operation: %s", op.class.String(), op.id)
 			_, md, _ := op.Render()
 			eventSend("operation", md)
 			op.lock.Unlock()
@@ -140,7 +141,7 @@ func (op *operation) Run() (chan error, error) {
 	}
 	op.lock.Unlock()
 
-	shared.LogDebugf("Started %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Started %s operation: %s", op.class.String(), op.id)
 	_, md, _ := op.Render()
 	eventSend("operation", md)
 
@@ -172,7 +173,7 @@ func (op *operation) Cancel() (chan error, error) {
 				op.lock.Unlock()
 				chanCancel <- err
 
-				shared.LogDebugf("Failed to cancel %s operation: %s: %s", op.class.String(), op.id, err)
+				logger.Debugf("Failed to cancel %s operation: %s: %s", op.class.String(), op.id, err)
 				_, md, _ := op.Render()
 				eventSend("operation", md)
 				return
@@ -184,13 +185,13 @@ func (op *operation) Cancel() (chan error, error) {
 			op.done()
 			chanCancel <- nil
 
-			shared.LogDebugf("Cancelled %s operation: %s", op.class.String(), op.id)
+			logger.Debugf("Cancelled %s operation: %s", op.class.String(), op.id)
 			_, md, _ := op.Render()
 			eventSend("operation", md)
 		}(op, oldStatus, chanCancel)
 	}
 
-	shared.LogDebugf("Cancelling %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Cancelling %s operation: %s", op.class.String(), op.id)
 	_, md, _ := op.Render()
 	eventSend("operation", md)
 
@@ -202,7 +203,7 @@ func (op *operation) Cancel() (chan error, error) {
 		chanCancel <- nil
 	}
 
-	shared.LogDebugf("Cancelled %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Cancelled %s operation: %s", op.class.String(), op.id)
 	_, md, _ = op.Render()
 	eventSend("operation", md)
 
@@ -227,17 +228,17 @@ func (op *operation) Connect(r *http.Request, w http.ResponseWriter) (chan error
 		if err != nil {
 			chanConnect <- err
 
-			shared.LogDebugf("Failed to handle %s operation: %s: %s", op.class.String(), op.id, err)
+			logger.Debugf("Failed to handle %s operation: %s: %s", op.class.String(), op.id, err)
 			return
 		}
 
 		chanConnect <- nil
 
-		shared.LogDebugf("Handled %s operation: %s", op.class.String(), op.id)
+		logger.Debugf("Handled %s operation: %s", op.class.String(), op.id)
 	}(op, chanConnect)
 	op.lock.Unlock()
 
-	shared.LogDebugf("Connected %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Connected %s operation: %s", op.class.String(), op.id)
 
 	return chanConnect, nil
 }
@@ -316,7 +317,7 @@ func (op *operation) UpdateResources(opResources map[string][]string) error {
 	op.resources = opResources
 	op.lock.Unlock()
 
-	shared.LogDebugf("Updated resources for %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Updated resources for %s operation: %s", op.class.String(), op.id)
 	_, md, _ := op.Render()
 	eventSend("operation", md)
 
@@ -342,7 +343,7 @@ func (op *operation) UpdateMetadata(opMetadata interface{}) error {
 	op.metadata = newMetadata
 	op.lock.Unlock()
 
-	shared.LogDebugf("Updated metadata for %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("Updated metadata for %s operation: %s", op.class.String(), op.id)
 	_, md, _ := op.Render()
 	eventSend("operation", md)
 
@@ -397,7 +398,7 @@ func operationCreate(opClass operationClass, opResources map[string][]string, op
 	operations[op.id] = &op
 	operationsLock.Unlock()
 
-	shared.LogDebugf("New %s operation: %s", op.class.String(), op.id)
+	logger.Debugf("New %s operation: %s", op.class.String(), op.id)
 	_, md, _ := op.Render()
 	eventSend("operation", md)
 
diff --git a/lxd/patches.go b/lxd/patches.go
index 28a2bf6..1123865 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -8,6 +8,7 @@ import (
 	"syscall"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 
 	log "gopkg.in/inconshreveable/log15.v2"
 )
@@ -49,7 +50,7 @@ type patch struct {
 }
 
 func (p *patch) apply(d *Daemon) error {
-	shared.LogDebugf("Applying patch: %s", p.name)
+	logger.Debugf("Applying patch: %s", p.name)
 
 	err := p.run(p.name, d)
 	if err != nil {
@@ -108,7 +109,7 @@ func patchInvalidProfileNames(name string, d *Daemon) error {
 
 	for _, profile := range profiles {
 		if strings.Contains(profile, "/") || shared.StringInSlice(profile, []string{".", ".."}) {
-			shared.LogInfo("Removing unreachable profile (invalid name)", log.Ctx{"name": profile})
+			logger.Info("Removing unreachable profile (invalid name)", log.Ctx{"name": profile})
 			err := dbProfileDelete(d.db, profile)
 			if err != nil {
 				return err
@@ -291,14 +292,14 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
-			shared.LogWarnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
+			logger.Warnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
 		}
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
 		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s.", err)
+			logger.Errorf("Failed to query database: %s.", err)
 			return err
 		}
 		poolID = tmp
@@ -330,7 +331,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			return err
 		}
 	} else { // Shouldn't happen.
-		shared.LogErrorf("Failed to query database: %s.", err)
+		logger.Errorf("Failed to query database: %s.", err)
 		return err
 	}
 
@@ -362,7 +363,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+			logger.Warnf("Storage volumes database already contains an entry for the container.")
 			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				return err
@@ -371,11 +372,11 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -394,7 +395,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 				output, err := storageRsyncCopy(oldContainerMntPoint, newContainerMntPoint)
 				if err != nil {
-					shared.LogErrorf("Failed to rsync: %s: %s.", output, err)
+					logger.Errorf("Failed to rsync: %s: %s.", output, err)
 					return err
 				}
 
@@ -450,7 +451,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
-				shared.LogWarnf("Storage volumes database already contains an entry for the snapshot.")
+				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
 				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
@@ -459,11 +460,11 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 				// Insert storage volumes for containers into the database.
 				_, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
-					shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
 				}
 			} else {
-				shared.LogErrorf("Failed to query database: %s", err)
+				logger.Errorf("Failed to query database: %s", err)
 				return err
 			}
 
@@ -481,7 +482,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 					output, err := storageRsyncCopy(oldSnapshotMntPoint, newSnapshotMntPoint)
 					if err != nil {
-						shared.LogErrorf("Failed to rsync: %s: %s.", output, err)
+						logger.Errorf("Failed to rsync: %s: %s.", output, err)
 						return err
 					}
 
@@ -531,7 +532,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the image.")
+			logger.Warnf("Storage volumes database already contains an entry for the image.")
 			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				return err
@@ -540,11 +541,11 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for image \"%s\".", img)
+				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -588,14 +589,14 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
-			shared.LogWarnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
+			logger.Warnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
 		}
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
 		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s.", err)
+			logger.Errorf("Failed to query database: %s.", err)
 			return err
 		}
 		poolID = tmp
@@ -627,7 +628,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 	} else { // Shouldn't happen.
-		shared.LogErrorf("Failed to query database: %s.", err)
+		logger.Errorf("Failed to query database: %s.", err)
 		return err
 	}
 
@@ -649,7 +650,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+			logger.Warnf("Storage volumes database already contains an entry for the container.")
 			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				return err
@@ -658,11 +659,11 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -685,7 +686,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			if err != nil {
 				output, err := storageRsyncCopy(oldContainerMntPoint, newContainerMntPoint)
 				if err != nil {
-					shared.LogErrorf("Failed to rsync: %s: %s.", output, err)
+					logger.Errorf("Failed to rsync: %s: %s.", output, err)
 					return err
 				}
 				err = os.RemoveAll(oldContainerMntPoint)
@@ -732,7 +733,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			if err != nil {
 				output, err := storageRsyncCopy(oldSnapshotMntPoint, newSnapshotMntPoint)
 				if err != nil {
-					shared.LogErrorf("Failed to rsync: %s: %s.", output, err)
+					logger.Errorf("Failed to rsync: %s: %s.", output, err)
 					return err
 				}
 				err = os.RemoveAll(oldSnapshotMntPoint)
@@ -766,7 +767,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the snapshot.")
+			logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
 			err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 			if err != nil {
 				return err
@@ -775,11 +776,11 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+				logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 	}
@@ -796,7 +797,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the image.")
+			logger.Warnf("Storage volumes database already contains an entry for the image.")
 			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				return err
@@ -805,11 +806,11 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for image \"%s\".", img)
+				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 	}
@@ -869,7 +870,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	// Activate volume group
 	err = storageVGActivate(defaultPoolName)
 	if err != nil {
-		shared.LogErrorf("Could not activate volume group \"%s\". Manual intervention needed.")
+		logger.Errorf("Could not activate volume group \"%s\". Manual intervention needed.", defaultPoolName)
 		return err
 	}
 
@@ -881,14 +882,14 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
-			shared.LogWarnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
+			logger.Warnf("Database already contains a valid entry for the storage pool: %s.", defaultPoolName)
 		}
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
 		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s.", err)
+			logger.Errorf("Failed to query database: %s.", err)
 			return err
 		}
 		poolID = tmp
@@ -910,7 +911,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		}
 		poolID = tmp
 	} else { // Shouldn't happen.
-		shared.LogErrorf("Failed to query database: %s.", err)
+		logger.Errorf("Failed to query database: %s.", err)
 		return err
 	}
 
@@ -919,7 +920,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	if !shared.PathExists(poolMntPoint) {
 		err = os.MkdirAll(poolMntPoint, 0711)
 		if err != nil {
-			shared.LogWarnf("Failed to create pool mountpoint: %s", poolMntPoint)
+			logger.Warnf("Failed to create pool mountpoint: %s", poolMntPoint)
 		}
 	}
 
@@ -929,7 +930,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		if !shared.PathExists(newContainersMntPoint) {
 			err = os.MkdirAll(newContainersMntPoint, 0711)
 			if err != nil {
-				shared.LogWarnf("Failed to create containers mountpoint: %s", newContainersMntPoint)
+				logger.Warnf("Failed to create containers mountpoint: %s", newContainersMntPoint)
 			}
 		}
 	}
@@ -952,7 +953,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+			logger.Warnf("Storage volumes database already contains an entry for the container.")
 			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				return err
@@ -961,11 +962,11 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -974,7 +975,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		if shared.IsMountPoint(oldContainerMntPoint) {
 			err := tryUnmount(oldContainerMntPoint, syscall.MNT_DETACH)
 			if err != nil {
-				shared.LogErrorf("Failed to unmount LVM logical volume \"%s\": %s.", oldContainerMntPoint, err)
+				logger.Errorf("Failed to unmount LVM logical volume \"%s\": %s.", oldContainerMntPoint, err)
 				return err
 			}
 		}
@@ -997,7 +998,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				if shared.PathExists(oldContainerMntPoint) && !shared.PathExists(newContainerMntPoint) {
 					err = os.Rename(oldContainerMntPoint, newContainerMntPoint)
 					if err != nil {
-						shared.LogErrorf("Failed to rename LVM container mountpoint from %s to %s: %s.", oldContainerMntPoint, newContainerMntPoint, err)
+						logger.Errorf("Failed to rename LVM container mountpoint from %s to %s: %s.", oldContainerMntPoint, newContainerMntPoint, err)
 						return err
 					}
 				}
@@ -1006,7 +1007,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				if shared.PathExists(oldContainerMntPoint + ".lv") {
 					err := os.Remove(oldContainerMntPoint + ".lv")
 					if err != nil {
-						shared.LogErrorf("Failed to remove old LVM container mountpoint %s: %s.", oldContainerMntPoint+".lv", err)
+						logger.Errorf("Failed to remove old LVM container mountpoint %s: %s.", oldContainerMntPoint+".lv", err)
 						return err
 					}
 				}
@@ -1014,7 +1015,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// Rename the logical volume.
 				msg, err := shared.TryRunCommand("lvrename", defaultPoolName, ctLvName, newContainerLvName)
 				if err != nil {
-					shared.LogErrorf("Failed to rename LVM logical volume from %s to %s: %s.", ctLvName, newContainerLvName, msg)
+					logger.Errorf("Failed to rename LVM logical volume from %s to %s: %s.", ctLvName, newContainerLvName, msg)
 					return err
 				}
 			} else if shared.PathExists(oldContainerMntPoint) && shared.IsDir(oldContainerMntPoint) {
@@ -1026,14 +1027,14 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// container.
 				ctStorage, err := storagePoolVolumeContainerLoadInit(d, ct)
 				if err != nil {
-					shared.LogErrorf("Failed to initialize new storage interface for LVM container %s: %s.", ct, err)
+					logger.Errorf("Failed to initialize new storage interface for LVM container %s: %s.", ct, err)
 					return err
 				}
 
 				// Load the container from the database.
 				ctStruct, err := containerLoadByName(d, ct)
 				if err != nil {
-					shared.LogErrorf("Failed to load LVM container %s: %s.", ct, err)
+					logger.Errorf("Failed to load LVM container %s: %s.", ct, err)
 					return err
 				}
 
@@ -1041,7 +1042,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// container.
 				err = ctStorage.ContainerCreate(ctStruct)
 				if err != nil {
-					shared.LogErrorf("Failed to create empty LVM logical volume for container %s: %s.", ct, err)
+					logger.Errorf("Failed to create empty LVM logical volume for container %s: %s.", ct, err)
 					return err
 				}
 
@@ -1050,7 +1051,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				if !shared.IsMountPoint(newContainerMntPoint) {
 					_, err = ctStorage.ContainerMount(ctStruct.Name(), ctStruct.Path())
 					if err != nil {
-						shared.LogErrorf("Failed to mount new empty LVM logical volume for container %s: %s.", ct, err)
+						logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s.", ct, err)
 						return err
 					}
 				}
@@ -1065,7 +1066,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// Remove the old container.
 				err = os.RemoveAll(oldContainerMntPoint)
 				if err != nil {
-					shared.LogErrorf("Failed to remove old container %s: %s.", oldContainerMntPoint, err)
+					logger.Errorf("Failed to remove old container %s: %s.", oldContainerMntPoint, err)
 					return err
 				}
 			}
@@ -1075,7 +1076,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		doesntMatter := false
 		err = createContainerMountpoint(newContainerMntPoint, oldContainerMntPoint, doesntMatter)
 		if err != nil {
-			shared.LogErrorf("Failed to create container mountpoint \"%s\" for LVM logical volume: %s.", newContainerMntPoint, err)
+			logger.Errorf("Failed to create container mountpoint \"%s\" for LVM logical volume: %s.", newContainerMntPoint, err)
 			return err
 		}
 
@@ -1107,7 +1108,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
-				shared.LogWarnf("Storage volumes database already contains an entry for the snapshot.")
+				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
 				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
@@ -1116,11 +1117,11 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// Insert storage volumes for containers into the database.
 				_, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
-					shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
 				}
 			} else {
-				shared.LogErrorf("Failed to query database: %s", err)
+				logger.Errorf("Failed to query database: %s", err)
 				return err
 			}
 
@@ -1149,7 +1150,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					if shared.IsMountPoint(oldSnapshotMntPoint) {
 						err := tryUnmount(oldSnapshotMntPoint, syscall.MNT_DETACH)
 						if err != nil {
-							shared.LogErrorf("Failed to unmount LVM logical volume \"%s\": %s.", oldSnapshotMntPoint, err)
+							logger.Errorf("Failed to unmount LVM logical volume \"%s\": %s.", oldSnapshotMntPoint, err)
 							return err
 						}
 					}
@@ -1159,7 +1160,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					if shared.PathExists(oldSnapshotMntPoint) && !shared.PathExists(newSnapshotMntPoint) {
 						err := os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 						if err != nil {
-							shared.LogErrorf("Failed to rename LVM container mountpoint from %s to %s: %s.", oldSnapshotMntPoint, newSnapshotMntPoint, err)
+							logger.Errorf("Failed to rename LVM container mountpoint from %s to %s: %s.", oldSnapshotMntPoint, newSnapshotMntPoint, err)
 							return err
 						}
 					}
@@ -1167,7 +1168,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					// Rename the logical volume.
 					msg, err := shared.TryRunCommand("lvrename", defaultPoolName, csLvName, newSnapshotLvName)
 					if err != nil {
-						shared.LogErrorf("Failed to rename LVM logical volume from %s to %s: %s.", csLvName, newSnapshotLvName, msg)
+						logger.Errorf("Failed to rename LVM logical volume from %s to %s: %s.", csLvName, newSnapshotLvName, msg)
 						return err
 					}
 				} else if shared.PathExists(oldSnapshotMntPoint) && shared.IsDir(oldSnapshotMntPoint) {
@@ -1179,14 +1180,14 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					// snapshot.
 					csStorage, err := storagePoolVolumeContainerLoadInit(d, cs)
 					if err != nil {
-						shared.LogErrorf("Failed to initialize new storage interface for LVM container %s: %s.", cs, err)
+						logger.Errorf("Failed to initialize new storage interface for LVM container %s: %s.", cs, err)
 						return err
 					}
 
 					// Load the snapshot from the database.
 					csStruct, err := containerLoadByName(d, cs)
 					if err != nil {
-						shared.LogErrorf("Failed to load LVM container %s: %s.", cs, err)
+						logger.Errorf("Failed to load LVM container %s: %s.", cs, err)
 						return err
 					}
 
@@ -1194,7 +1195,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					// for the snapshot.
 					err = csStorage.ContainerSnapshotCreateEmpty(csStruct)
 					if err != nil {
-						shared.LogErrorf("Failed to create empty LVM logical volume for container %s: %s.", cs, err)
+						logger.Errorf("Failed to create empty LVM logical volume for container %s: %s.", cs, err)
 						return err
 					}
 
@@ -1204,7 +1205,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					if !shared.IsMountPoint(newSnapshotMntPoint) {
 						_, err = csStorage.ContainerMount(csStruct.Name(), csStruct.Path())
 						if err != nil {
-							shared.LogErrorf("Failed to mount new empty LVM logical volume for container %s: %s.", cs, err)
+							logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s.", cs, err)
 							return err
 						}
 					}
@@ -1219,7 +1220,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					// Remove the old snapshot.
 					err = os.RemoveAll(oldSnapshotMntPoint)
 					if err != nil {
-						shared.LogErrorf("Failed to remove old container %s: %s.", oldSnapshotMntPoint, err)
+						logger.Errorf("Failed to remove old container %s: %s.", oldSnapshotMntPoint, err)
 						return err
 					}
 				}
@@ -1252,7 +1253,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		if !shared.IsMountPoint(newContainerMntPoint) {
 			err := tryMount(containerLvDevPath, newContainerMntPoint, lvFsType, 0, mountOptions)
 			if err != nil {
-				shared.LogErrorf("Failed to mount LVM logical \"%s\" onto \"%s\" : %s.", containerLvDevPath, newContainerMntPoint, err)
+				logger.Errorf("Failed to mount LVM logical \"%s\" onto \"%s\" : %s.", containerLvDevPath, newContainerMntPoint, err)
 				return err
 			}
 		}
@@ -1278,7 +1279,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the image.")
+			logger.Warnf("Storage volumes database already contains an entry for the image.")
 			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				return err
@@ -1287,11 +1288,11 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for image \"%s\".", img)
+				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -1381,14 +1382,14 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(poolName, pools) {
-			shared.LogWarnf("Database already contains a valid entry for the storage pool: %s.", poolName)
+			logger.Warnf("Database already contains a valid entry for the storage pool: %s.", poolName)
 		}
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
 		tmp, pool, err := dbStoragePoolGet(d.db, poolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s.", err)
+			logger.Errorf("Failed to query database: %s.", err)
 			return err
 		}
 		poolID = tmp
@@ -1433,11 +1434,11 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		// (Use a tmp variable as Go's scoping is freaking me out.)
 		tmp, err := dbStoragePoolCreate(d.db, poolName, defaultStorageTypeName, poolConfig)
 		if err != nil {
-			shared.LogWarnf("Storage pool already exists in the database. Proceeding...")
+			logger.Warnf("Storage pool already exists in the database. Proceeding...")
 		}
 		poolID = tmp
 	} else { // Shouldn't happen.
-		shared.LogErrorf("Failed to query database: %s.", err)
+		logger.Errorf("Failed to query database: %s.", err)
 		return err
 	}
 
@@ -1452,7 +1453,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		if !shared.PathExists(containersSubvolumePath) {
 			err := os.MkdirAll(containersSubvolumePath, 0711)
 			if err != nil {
-				shared.LogWarnf("Failed to create path: %s.", containersSubvolumePath)
+				logger.Warnf("Failed to create path: %s.", containersSubvolumePath)
 			}
 		}
 	}
@@ -1469,7 +1470,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the container.")
+			logger.Warnf("Storage volumes database already contains an entry for the container.")
 			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				return err
@@ -1478,11 +1479,11 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, ct, storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for container \"%s\".", ct)
+				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -1496,7 +1497,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		if shared.IsMountPoint(oldContainerMntPoint) {
 			_, err := shared.TryRunCommand("zfs", "unmount", "-f", ctDataset)
 			if err != nil {
-				shared.LogWarnf("Failed to unmount ZFS filesystem via zfs unmount. Trying lazy umount (MNT_DETACH)...")
+				logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount. Trying lazy umount (MNT_DETACH)...")
 				err := tryUnmount(oldContainerMntPoint, syscall.MNT_DETACH)
 				if err != nil {
 					failedUpgradeEntities = append(failedUpgradeEntities, fmt.Sprintf("containers/%s: Failed to umount zfs filesystem.", ct))
@@ -1515,7 +1516,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		newContainerMntPoint := getContainerMountPoint(poolName, ct)
 		err = createContainerMountpoint(newContainerMntPoint, oldContainerMntPoint, doesntMatter)
 		if err != nil {
-			shared.LogWarnf("Failed to create mountpoint for the container: %s.", newContainerMntPoint)
+			logger.Warnf("Failed to create mountpoint for the container: %s.", newContainerMntPoint)
 			failedUpgradeEntities = append(failedUpgradeEntities, fmt.Sprintf("containers/%s: Failed to create container mountpoint: %s", ct, err))
 			continue
 		}
@@ -1528,7 +1529,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			fmt.Sprintf("mountpoint=%s", newContainerMntPoint),
 			ctDataset)
 		if err != nil {
-			shared.LogWarnf("Failed to set new ZFS mountpoint: %s.", output)
+			logger.Warnf("Failed to set new ZFS mountpoint: %s.", output)
 			failedUpgradeEntities = append(failedUpgradeEntities, fmt.Sprintf("containers/%s: Failed to set new zfs mountpoint: %s", ct, err))
 			continue
 		}
@@ -1536,7 +1537,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		// Check if we need to account for snapshots for this container.
 		ctSnapshots, err := dbContainerGetSnapshots(d.db, ct)
 		if err != nil {
-			shared.LogErrorf("Failed to query database")
+			logger.Errorf("Failed to query database")
 			return err
 		}
 
@@ -1555,7 +1556,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
-				shared.LogWarnf("Storage volumes database already contains an entry for the snapshot.")
+				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
 				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
@@ -1564,11 +1565,11 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 				// Insert storage volumes for containers into the database.
 				_, err := dbStoragePoolVolumeCreate(d.db, cs, storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
-					shared.LogErrorf("Could not insert a storage volume for snapshot \"%s\".", cs)
+					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
 				}
 			} else {
-				shared.LogErrorf("Failed to query database: %s", err)
+				logger.Errorf("Failed to query database: %s", err)
 				return err
 			}
 
@@ -1578,7 +1579,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			if !shared.PathExists(newSnapshotMntPoint) {
 				err = os.MkdirAll(newSnapshotMntPoint, 0711)
 				if err != nil {
-					shared.LogWarnf("Failed to create mountpoint for snapshot: %s.", newSnapshotMntPoint)
+					logger.Warnf("Failed to create mountpoint for snapshot: %s.", newSnapshotMntPoint)
 					failedUpgradeEntities = append(failedUpgradeEntities, fmt.Sprintf("snapshots/%s: Failed to create mountpoint for snapshot.", cs))
 					continue
 				}
@@ -1593,7 +1594,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			if !shared.PathExists(newSnapshotsMntPoint) {
 				err := os.Symlink(newSnapshotsMntPoint, snapshotsPath)
 				if err != nil {
-					shared.LogWarnf("Failed to create symlink for snapshots: %s -> %s.", snapshotsPath, newSnapshotsMntPoint)
+					logger.Warnf("Failed to create symlink for snapshots: %s -> %s.", snapshotsPath, newSnapshotsMntPoint)
 				}
 			}
 		}
@@ -1611,7 +1612,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
-			shared.LogWarnf("Storage volumes database already contains an entry for the image.")
+			logger.Warnf("Storage volumes database already contains an entry for the image.")
 			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				return err
@@ -1620,11 +1621,11 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			// Insert storage volumes for containers into the database.
 			_, err := dbStoragePoolVolumeCreate(d.db, img, storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
-				shared.LogErrorf("Could not insert a storage volume for image \"%s\".", img)
+				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
 			}
 		} else {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -1632,7 +1633,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		if !shared.PathExists(imageMntPoint) {
 			err := os.MkdirAll(imageMntPoint, 0700)
 			if err != nil {
-				shared.LogWarnf("Failed to create image mountpoint. Proceeding...")
+				logger.Warnf("Failed to create image mountpoint. Proceeding...")
 			}
 		}
 
@@ -1644,10 +1645,10 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		if shared.PathExists(oldImageMntPoint) && shared.IsMountPoint(oldImageMntPoint) {
 			_, err := shared.TryRunCommand("zfs", "unmount", "-f", imageDataset)
 			if err != nil {
-				shared.LogWarnf("Failed to unmount ZFS filesystem via zfs unmount. Trying lazy umount (MNT_DETACH)...")
+				logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount. Trying lazy umount (MNT_DETACH)...")
 				err := tryUnmount(oldImageMntPoint, syscall.MNT_DETACH)
 				if err != nil {
-					shared.LogWarnf("Failed to unmount ZFS filesystem: %s", err)
+					logger.Warnf("Failed to unmount ZFS filesystem: %s", err)
 				}
 			}
 
@@ -1658,7 +1659,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		// automatically mounted.
 		output, err := shared.RunCommand("zfs", "set", "mountpoint=none", imageDataset)
 		if err != nil {
-			shared.LogWarnf("Failed to set new ZFS mountpoint: %s.", output)
+			logger.Warnf("Failed to set new ZFS mountpoint: %s.", output)
 		}
 	}
 
@@ -1682,7 +1683,7 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 		for _, pName := range profiles {
 			pID, p, err := dbProfileGet(d.db, pName)
 			if err != nil {
-				shared.LogErrorf("Could not query database: %s.", err)
+				logger.Errorf("Could not query database: %s.", err)
 				return err
 			}
 
@@ -1728,28 +1729,28 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 
 			err = dbProfileConfigClear(tx, pID)
 			if err != nil {
-				shared.LogErrorf("Failed to clear old profile configuration for profile %s: %s.", pName, err)
+				logger.Errorf("Failed to clear old profile configuration for profile %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
 
 			err = dbProfileConfigAdd(tx, pID, p.Config)
 			if err != nil {
-				shared.LogErrorf("Failed to add new profile configuration: %s: %s.", pName, err)
+				logger.Errorf("Failed to add new profile configuration: %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
 
 			err = dbDevicesAdd(tx, "profile", pID, p.Devices)
 			if err != nil {
-				shared.LogErrorf("Failed to add new profile profile root disk device: %s: %s.", pName, err)
+				logger.Errorf("Failed to add new profile profile root disk device: %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
 
 			err = tx.Commit()
 			if err != nil {
-				shared.LogErrorf("Failed to commit database transaction: %s: %s.", pName, err)
+				logger.Errorf("Failed to commit database transaction: %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
@@ -1830,12 +1831,12 @@ func patchStorageApiV1(name string, d *Daemon) error {
 		return nil
 	} else if err != nil {
 		// Database is screwed.
-		shared.LogErrorf("Failed to query database: %s", err)
+		logger.Errorf("Failed to query database: %s", err)
 		return err
 	}
 
 	if len(pools) != 1 {
-		shared.LogWarnf("More than one storage pool found. Not rerunning upgrade.")
+		logger.Warnf("More than one storage pool found. Not rerunning upgrade.")
 		return nil
 	}
 
@@ -1890,14 +1891,14 @@ func patchStorageApiKeys(name string, d *Daemon) error {
 		return nil
 	} else if err != nil {
 		// Database is screwed.
-		shared.LogErrorf("Failed to query database: %s", err)
+		logger.Errorf("Failed to query database: %s", err)
 		return err
 	}
 
 	for _, poolName := range pools {
 		_, pool, err := dbStoragePoolGet(d.db, poolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -1945,14 +1946,14 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 		if err == NoSuchObjectError {
 			return nil
 		}
-		shared.LogErrorf("Failed to query database: %s", err)
+		logger.Errorf("Failed to query database: %s", err)
 		return err
 	}
 
 	for _, poolName := range pools {
 		poolID, pool, err := dbStoragePoolGet(d.db, poolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -2093,14 +2094,14 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
 		if err == NoSuchObjectError {
 			return nil
 		}
-		shared.LogErrorf("Failed to query database: %s", err)
+		logger.Errorf("Failed to query database: %s", err)
 		return err
 	}
 
 	for _, poolName := range pools {
 		_, pool, err := dbStoragePoolGet(d.db, poolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -2150,14 +2151,14 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 		if err == NoSuchObjectError {
 			return nil
 		}
-		shared.LogErrorf("Failed to query database: %s", err)
+		logger.Errorf("Failed to query database: %s", err)
 		return err
 	}
 
 	for _, poolName := range pools {
 		poolID, pool, err := dbStoragePoolGet(d.db, poolName)
 		if err != nil {
-			shared.LogErrorf("Failed to query database: %s", err)
+			logger.Errorf("Failed to query database: %s", err)
 			return err
 		}
 
@@ -2188,7 +2189,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 
 		poolName := pool.Config["lvm.vg_name"]
 		if poolName == "" {
-			shared.LogErrorf("The \"lvm.vg_name\" key should not be empty.")
+			logger.Errorf("The \"lvm.vg_name\" key should not be empty.")
 			return fmt.Errorf("The \"lvm.vg_name\" key should not be empty.")
 		}
 
@@ -2211,7 +2212,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 			lvmLvDevPath := getLvmDevPath(poolName, volumeTypeApiEndpoint, lvmName)
 			size, err := lvmGetLVSize(lvmLvDevPath)
 			if err != nil {
-				shared.LogErrorf("Failed to detect size of logical volume: %s.", err)
+				logger.Errorf("Failed to detect size of logical volume: %s.", err)
 				return err
 			}
 
diff --git a/lxd/profiles.go b/lxd/profiles.go
index 4d72322..07dc1a3 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -37,7 +38,7 @@ func profilesGet(d *Daemon, r *http.Request) Response {
 		} else {
 			profile, err := doProfileGet(d, name)
 			if err != nil {
-				shared.LogError("Failed to get profile", log.Ctx{"profile": name})
+				logger.Error("Failed to get profile", log.Ctx{"profile": name})
 				continue
 			}
 			resultMap[i] = profile
@@ -144,7 +145,7 @@ func getContainersWithProfile(d *Daemon, profile string) []container {
 	for _, name := range output {
 		c, err := containerLoadByName(d, name)
 		if err != nil {
-			shared.LogError("Failed opening container", log.Ctx{"container": name})
+			logger.Error("Failed opening container", log.Ctx{"container": name})
 			continue
 		}
 		results = append(results, c)
diff --git a/lxd/rsync.go b/lxd/rsync.go
index 00d107f..456bd5a 100644
--- a/lxd/rsync.go
+++ b/lxd/rsync.go
@@ -11,6 +11,7 @@ import (
 	"github.com/gorilla/websocket"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func rsyncSendSetup(path string) (*exec.Cmd, net.Conn, io.ReadCloser, error) {
@@ -115,7 +116,7 @@ func RsyncSend(path string, conn *websocket.Conn, readWrapper func(io.ReadCloser
 
 	err = cmd.Wait()
 	if err != nil {
-		shared.LogErrorf("Rsync send failed: %s: %s: %s", path, err, string(output))
+		logger.Errorf("Rsync send failed: %s: %s: %s", path, err, string(output))
 	}
 
 	<-readDone
@@ -171,7 +172,7 @@ func RsyncRecv(path string, conn *websocket.Conn, writeWrapper func(io.WriteClos
 
 	err = cmd.Wait()
 	if err != nil {
-		shared.LogErrorf("Rsync receive failed: %s: %s: %s", path, err, string(output))
+		logger.Errorf("Rsync receive failed: %s: %s: %s", path, err, string(output))
 	}
 
 	<-readDone
diff --git a/lxd/storage.go b/lxd/storage.go
index a0bb843..99e3ba7 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -16,6 +16,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 // lxdStorageLockMap is a hashmap that allows functions to check whether the
@@ -106,7 +107,7 @@ func filesystemDetect(path string) (string, error) {
 	case filesystemSuperMagicNfs:
 		return "nfs", nil
 	default:
-		shared.LogDebugf("Unknown backing filesystem type: 0x%x", fs.Type)
+		logger.Debugf("Unknown backing filesystem type: 0x%x", fs.Type)
 		return string(fs.Type), nil
 	}
 }
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 00d6e34..cb14b58 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -17,6 +17,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 var btrfsMntOptions = "user_subvol_rm_allowed"
@@ -68,7 +69,7 @@ func (s *storageBtrfs) StorageCoreInit() error {
 		return fmt.Errorf("The 'btrfs' tool isn't working properly")
 	}
 
-	shared.LogDebugf("Initializing a BTRFS driver.")
+	logger.Debugf("Initializing a BTRFS driver.")
 	return nil
 }
 
@@ -84,12 +85,12 @@ func (s *storageBtrfs) StoragePoolInit() error {
 func (s *storageBtrfs) StoragePoolCheck() error {
 	// FIXEM(brauner): Think of something smart or useful (And then think
 	// again if it is worth implementing it. :)).
-	shared.LogDebugf("Checking BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checking BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolCreate() error {
-	shared.LogInfof("Creating BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Creating BTRFS storage pool \"%s\".", s.pool.Name)
 
 	isBlockDev := false
 	source := s.pool.Config["source"]
@@ -186,10 +187,10 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		// we granted it above. So try to call btrfs filesystem show and
 		// parse it out. (I __hate__ this!)
 		if devUUID == "" {
-			shared.LogWarnf("Failed to detect UUID by looking at /dev/disk/by-uuid.")
+			logger.Warnf("Failed to detect UUID by looking at /dev/disk/by-uuid.")
 			devUUID, err1 = s.btrfsLookupFsUUID(source)
 			if err1 != nil {
-				shared.LogErrorf("Failed to detect UUID by parsing filesystem info.")
+				logger.Errorf("Failed to detect UUID by parsing filesystem info.")
 				return err1
 			}
 		}
@@ -245,12 +246,12 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		return err
 	}
 
-	shared.LogInfof("Created BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Created BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolDelete() error {
-	shared.LogInfof("Deleting BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleting BTRFS storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -289,7 +290,7 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 		} else {
 			msg = fmt.Sprintf("Failed to lookup disk device with UUID: %s: %s.", source, err)
 		}
-		shared.LogDebugf(msg)
+		logger.Debugf(msg)
 	} else {
 		var err error
 		cleanSource := filepath.Clean(source)
@@ -311,12 +312,12 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 	// Remove the mountpoint for the storage pool.
 	os.RemoveAll(getStoragePoolMountPoint(s.pool.Name))
 
-	shared.LogInfof("Deleted BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleted BTRFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolMount() (bool, error) {
-	shared.LogDebugf("Mounting BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Mounting BTRFS storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -330,7 +331,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage pool.
@@ -415,12 +416,12 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Mounted BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Mounted BTRFS storage pool \"%s\".", s.pool.Name)
 	return true, nil
 }
 
 func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
-	shared.LogDebugf("Unmounting BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Unmounting BTRFS storage pool \"%s\".", s.pool.Name)
 
 	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
 
@@ -429,7 +430,7 @@ func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage pool.
@@ -457,7 +458,7 @@ func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 		}
 	}
 
-	shared.LogDebugf("Unmounted BTRFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Unmounted BTRFS storage pool \"%s\".", s.pool.Name)
 	return true, nil
 }
 
@@ -479,7 +480,7 @@ func (s *storageBtrfs) GetContainerPoolInfo() (int64, string) {
 
 // Functions dealing with storage volumes.
 func (s *storageBtrfs) StoragePoolVolumeCreate() error {
-	shared.LogInfof("Creating BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Creating BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -502,12 +503,12 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 		return err
 	}
 
-	shared.LogInfof("Created BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Created BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolVolumeDelete() error {
-	shared.LogInfof("Deleting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -529,12 +530,12 @@ func (s *storageBtrfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	shared.LogInfof("Deleted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) StoragePoolVolumeMount() (bool, error) {
-	shared.LogDebugf("Mounting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -542,7 +543,7 @@ func (s *storageBtrfs) StoragePoolVolumeMount() (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Mounted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted BTRFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
@@ -569,7 +570,7 @@ func (s *storageBtrfs) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageBtrfs) ContainerCreate(container container) error {
-	shared.LogDebugf("Creating empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -604,13 +605,13 @@ func (s *storageBtrfs) ContainerCreate(container container) error {
 		return err
 	}
 
-	shared.LogDebugf("Created empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return container.TemplateApply("create")
 }
 
 // And this function is why I started hating on btrfs...
 func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint string) error {
-	shared.LogDebugf("Creating BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -644,7 +645,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -691,7 +692,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 		}
 	}
 
-	shared.LogDebugf("Created BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return container.TemplateApply("create")
 }
 
@@ -700,7 +701,7 @@ func (s *storageBtrfs) ContainerCanRestore(container container, sourceContainer
 }
 
 func (s *storageBtrfs) ContainerDelete(container container) error {
-	shared.LogDebugf("Deleting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// The storage pool needs to be mounted.
 	_, err := s.StoragePoolMount()
@@ -740,7 +741,7 @@ func (s *storageBtrfs) ContainerDelete(container container) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -818,7 +819,7 @@ func (s *storageBtrfs) copySnapshot(target container, source container) error {
 }
 
 func (s *storageBtrfs) ContainerCopy(target container, source container, containerOnly bool) error {
-	shared.LogDebugf("Copying BTRFS container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copying BTRFS container storage %s -> %s.", source.Name(), target.Name())
 
 	// The storage pool needs to be mounted.
 	_, err := s.StoragePoolMount()
@@ -846,7 +847,7 @@ func (s *storageBtrfs) ContainerCopy(target container, source container, contain
 	}
 
 	if containerOnly {
-		shared.LogDebugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -856,7 +857,7 @@ func (s *storageBtrfs) ContainerCopy(target container, source container, contain
 	}
 
 	if len(snapshots) == 0 {
-		shared.LogDebugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -870,7 +871,7 @@ func (s *storageBtrfs) ContainerCopy(target container, source container, contain
 		newSnapName := fmt.Sprintf("%s/%s", target.Name(), fields[1])
 		targetSnapshot, err := containerLoadByName(s.d, newSnapName)
 		if err != nil {
-			shared.LogErrorf("1111: %s", newSnapName)
+			logger.Errorf("1111: %s", newSnapName)
 			return err
 		}
 
@@ -880,12 +881,12 @@ func (s *storageBtrfs) ContainerCopy(target container, source container, contain
 		}
 	}
 
-	shared.LogDebugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copied BTRFS container storage %s -> %s.", source.Name(), target.Name())
 	return nil
 }
 
 func (s *storageBtrfs) ContainerMount(name string, path string) (bool, error) {
-	shared.LogDebugf("Mounting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -893,7 +894,7 @@ func (s *storageBtrfs) ContainerMount(name string, path string) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Mounted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted BTRFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
@@ -902,7 +903,7 @@ func (s *storageBtrfs) ContainerUmount(name string, path string) (bool, error) {
 }
 
 func (s *storageBtrfs) ContainerRename(container container, newName string) error {
-	shared.LogDebugf("Renaming BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -946,12 +947,12 @@ func (s *storageBtrfs) ContainerRename(container container, newName string) erro
 		}
 	}
 
-	shared.LogDebugf("Renamed BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerRestore(container container, sourceContainer container) error {
-	shared.LogDebugf("Restoring BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restoring BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -1007,7 +1008,7 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 			output, err := storageRsyncCopy(sourceContainerSubvolumeName, targetContainerSubvolumeName)
 			if err != nil {
 				s.ContainerDelete(container)
-				shared.LogErrorf("ContainerRestore: rsync failed: %s.", string(output))
+				logger.Errorf("ContainerRestore: rsync failed: %s.", string(output))
 				failure = err
 			}
 		} else {
@@ -1032,12 +1033,12 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 		os.RemoveAll(backupTargetContainerSubvolumeName)
 	}
 
-	shared.LogDebugf("Restored BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restored BTRFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return failure
 }
 
 func (s *storageBtrfs) ContainerSetQuota(container container, size int64) error {
-	shared.LogDebugf("Setting BTRFS quota for container \"%s\".", container.Name())
+	logger.Debugf("Setting BTRFS quota for container \"%s\".", container.Name())
 
 	subvol := container.Path()
 
@@ -1057,7 +1058,7 @@ func (s *storageBtrfs) ContainerSetQuota(container container, size int64) error
 		return fmt.Errorf("Failed to set btrfs quota: %s", output)
 	}
 
-	shared.LogDebugf("Set BTRFS quota for container \"%s\".", container.Name())
+	logger.Debugf("Set BTRFS quota for container \"%s\".", container.Name())
 	return nil
 }
 
@@ -1066,7 +1067,7 @@ func (s *storageBtrfs) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
-	shared.LogDebugf("Creating BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1103,12 +1104,12 @@ func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer container, sour
 		return err
 	}
 
-	shared.LogDebugf("Created BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer container) error {
-	shared.LogDebugf("Deleting BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1134,12 +1135,12 @@ func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer container) erro
 		os.Remove(snapshotMntPointSymlink)
 	}
 
-	shared.LogDebugf("Deleted BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotStart(container container) (bool, error) {
-	shared.LogDebugf("Initializing BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initializing BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1149,7 +1150,7 @@ func (s *storageBtrfs) ContainerSnapshotStart(container container) (bool, error)
 	snapshotSubvolumeName := getSnapshotMountPoint(s.pool.Name, container.Name())
 	roSnapshotSubvolumeName := fmt.Sprintf("%s.ro", snapshotSubvolumeName)
 	if shared.PathExists(roSnapshotSubvolumeName) {
-		shared.LogDebugf("The BTRFS snapshot is already mounted read-write.")
+		logger.Debugf("The BTRFS snapshot is already mounted read-write.")
 		return false, nil
 	}
 
@@ -1163,12 +1164,12 @@ func (s *storageBtrfs) ContainerSnapshotStart(container container) (bool, error)
 		return false, err
 	}
 
-	shared.LogDebugf("Initialized BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initialized BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageBtrfs) ContainerSnapshotStop(container container) (bool, error) {
-	shared.LogDebugf("Stopping BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopping BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1178,7 +1179,7 @@ func (s *storageBtrfs) ContainerSnapshotStop(container container) (bool, error)
 	snapshotSubvolumeName := getSnapshotMountPoint(s.pool.Name, container.Name())
 	roSnapshotSubvolumeName := fmt.Sprintf("%s.ro", snapshotSubvolumeName)
 	if !shared.PathExists(roSnapshotSubvolumeName) {
-		shared.LogDebugf("The BTRFS snapshot is currently not mounted read-write.")
+		logger.Debugf("The BTRFS snapshot is currently not mounted read-write.")
 		return false, nil
 	}
 
@@ -1192,13 +1193,13 @@ func (s *storageBtrfs) ContainerSnapshotStop(container container) (bool, error)
 		return false, err
 	}
 
-	shared.LogDebugf("Stopped BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopped BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 // ContainerSnapshotRename renames a snapshot of a container.
 func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer container, newName string) error {
-	shared.LogDebugf("Renaming BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -1215,14 +1216,14 @@ func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer container, newN
 		return err
 	}
 
-	shared.LogDebugf("Renamed BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed BTRFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 // Needed for live migration where an empty snapshot needs to be created before
 // rsyncing into it.
 func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
-	shared.LogDebugf("Creating empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// Mount the storage pool.
 	_, err := s.StoragePoolMount()
@@ -1256,12 +1257,12 @@ func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container)
 		}
 	}
 
-	shared.LogDebugf("Created empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageCreate(fingerprint string) error {
-	shared.LogDebugf("Creating BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Creating BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	// Create the subvolume.
 	source := s.pool.Config["source"]
@@ -1338,12 +1339,12 @@ func (s *storageBtrfs) ImageCreate(fingerprint string) error {
 
 	undo = false
 
-	shared.LogDebugf("Created BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Created BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageDelete(fingerprint string) error {
-	shared.LogDebugf("Deleting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -1372,12 +1373,12 @@ func (s *storageBtrfs) ImageDelete(fingerprint string) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
 func (s *storageBtrfs) ImageMount(fingerprint string) (bool, error) {
-	shared.LogDebugf("Mounting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Mounting BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	// The storage pool must be mounted.
 	_, err := s.StoragePoolMount()
@@ -1385,7 +1386,7 @@ func (s *storageBtrfs) ImageMount(fingerprint string) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Mounted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Mounted BTRFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return true, nil
 }
 
@@ -1408,7 +1409,7 @@ func btrfsSubVolumeCreate(subvol string) error {
 		"create",
 		subvol)
 	if err != nil {
-		shared.LogErrorf("Failed to create BTRFS subvolume \"%s\": %s.", subvol, output)
+		logger.Errorf("Failed to create BTRFS subvolume \"%s\": %s.", subvol, output)
 		return err
 	}
 
@@ -1587,7 +1588,7 @@ func (s *storageBtrfs) btrfsPoolVolumesSnapshot(source string, dest string, read
 		// also don't make subvolumes readonly.
 		readonly = false
 
-		shared.LogWarnf("Subvolumes detected, ignoring ro flag.")
+		logger.Warnf("Subvolumes detected, ignoring ro flag.")
 	}
 
 	// First snapshot the root
@@ -1731,12 +1732,12 @@ func (s *btrfsMigrationSourceDriver) send(conn *websocket.Conn, btrfsPath string
 
 	output, err := ioutil.ReadAll(stderr)
 	if err != nil {
-		shared.LogErrorf("Problem reading btrfs send stderr: %s.")
+		logger.Errorf("Problem reading btrfs send stderr: %s.", err)
 	}
 
 	err = cmd.Wait()
 	if err != nil {
-		shared.LogErrorf("Problem with btrfs send: %s.", string(output))
+		logger.Errorf("Problem with btrfs send: %s.", string(output))
 	}
 
 	return err
@@ -1909,7 +1910,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		// Remove the existing pre-created subvolume
 		err := btrfsSubVolumesDelete(targetPath)
 		if err != nil {
-			shared.LogErrorf("Failed to delete pre-created BTRFS subvolume: %s.", btrfsPath)
+			logger.Errorf("Failed to delete pre-created BTRFS subvolume: %s.", btrfsPath)
 			return err
 		}
 
@@ -1937,12 +1938,12 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 		output, err := ioutil.ReadAll(stderr)
 		if err != nil {
-			shared.LogDebugf("Problem reading btrfs receive stderr %s.", err)
+			logger.Debugf("Problem reading btrfs receive stderr %s.", err)
 		}
 
 		err = cmd.Wait()
 		if err != nil {
-			shared.LogErrorf("Problem with btrfs receive: %s.", string(output))
+			logger.Errorf("Problem with btrfs receive: %s.", string(output))
 			return err
 		}
 
@@ -1954,7 +1955,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 			err = s.btrfsPoolVolumesSnapshot(receivedSnapshot, targetPath, false)
 		}
 		if err != nil {
-			shared.LogErrorf("Problem with btrfs snapshot: %s.", err)
+			logger.Errorf("Problem with btrfs snapshot: %s.", err)
 			return err
 		}
 
@@ -1962,7 +1963,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 		err = btrfsSubVolumesDelete(receivedSnapshot)
 		if err != nil {
-			shared.LogErrorf("Failed to delete BTRFS subvolume \"%s\": %s.", btrfsPath, err)
+			logger.Errorf("Failed to delete BTRFS subvolume \"%s\": %s.", btrfsPath, err)
 			return err
 		}
 
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 1962245..c50a77b 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -10,6 +10,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type storageDir struct {
@@ -26,7 +27,7 @@ func (s *storageDir) StorageCoreInit() error {
 	s.sTypeName = typeName
 	s.sTypeVersion = "1"
 
-	shared.LogDebugf("Initializing a DIR driver.")
+	logger.Debugf("Initializing a DIR driver.")
 	return nil
 }
 
@@ -42,12 +43,12 @@ func (s *storageDir) StoragePoolInit() error {
 
 // Initialize a full storage interface.
 func (s *storageDir) StoragePoolCheck() error {
-	shared.LogDebugf("Checking DIR storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checking DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolCreate() error {
-	shared.LogInfof("Creating DIR storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Creating DIR storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -93,12 +94,12 @@ func (s *storageDir) StoragePoolCreate() error {
 
 	revert = false
 
-	shared.LogInfof("Created DIR storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Created DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolDelete() error {
-	shared.LogInfof("Deleting DIR storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleting DIR storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -125,7 +126,7 @@ func (s *storageDir) StoragePoolDelete() error {
 		}
 	}
 
-	shared.LogInfof("Deleted DIR storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleted DIR storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -163,7 +164,7 @@ func (s *storageDir) StoragePoolUpdate(writable *api.StoragePoolPut, changedConf
 
 // Functions dealing with storage pools.
 func (s *storageDir) StoragePoolVolumeCreate() error {
-	shared.LogInfof("Creating DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Creating DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -176,12 +177,12 @@ func (s *storageDir) StoragePoolVolumeCreate() error {
 		return err
 	}
 
-	shared.LogInfof("Created DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Created DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) StoragePoolVolumeDelete() error {
-	shared.LogInfof("Deleting DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleting DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -198,7 +199,7 @@ func (s *storageDir) StoragePoolVolumeDelete() error {
 		return err
 	}
 
-	shared.LogInfof("Deleted DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleted DIR storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -221,7 +222,7 @@ func (s *storageDir) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageDir) ContainerCreate(container container) error {
-	shared.LogDebugf("Creating empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -248,12 +249,12 @@ func (s *storageDir) ContainerCreate(container container) error {
 
 	revert = false
 
-	shared.LogDebugf("Created empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerCreateFromImage(container container, imageFingerprint string) error {
-	shared.LogDebugf("Creating DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -295,7 +296,7 @@ func (s *storageDir) ContainerCreateFromImage(container container, imageFingerpr
 
 	revert = false
 
-	shared.LogDebugf("Created DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -304,7 +305,7 @@ func (s *storageDir) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageDir) ContainerDelete(container container) error {
-	shared.LogDebugf("Deleting DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -350,7 +351,7 @@ func (s *storageDir) ContainerDelete(container container) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted DIR storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -408,7 +409,7 @@ func (s *storageDir) copySnapshot(target container, source container) error {
 }
 
 func (s *storageDir) ContainerCopy(target container, source container, containerOnly bool) error {
-	shared.LogDebugf("Copying DIR container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copying DIR container storage %s -> %s.", source.Name(), target.Name())
 
 	ourStart, err := source.StorageStart()
 	if err != nil {
@@ -430,7 +431,7 @@ func (s *storageDir) ContainerCopy(target container, source container, container
 	}
 
 	if containerOnly {
-		shared.LogDebugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -440,7 +441,7 @@ func (s *storageDir) ContainerCopy(target container, source container, container
 	}
 
 	if len(snapshots) == 0 {
-		shared.LogDebugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -463,7 +464,7 @@ func (s *storageDir) ContainerCopy(target container, source container, container
 		}
 	}
 
-	shared.LogDebugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copied DIR container storage %s -> %s.", source.Name(), target.Name())
 	return nil
 }
 
@@ -476,7 +477,7 @@ func (s *storageDir) ContainerUmount(name string, path string) (bool, error) {
 }
 
 func (s *storageDir) ContainerRename(container container, newName string) error {
-	shared.LogDebugf("Renaming DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -521,12 +522,12 @@ func (s *storageDir) ContainerRename(container container, newName string) error
 		}
 	}
 
-	shared.LogDebugf("Renamed DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageDir) ContainerRestore(container container, sourceContainer container) error {
-	shared.LogDebugf("Restoring DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restoring DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 
 	targetPath := container.Path()
 	sourcePath := sourceContainer.Path()
@@ -542,7 +543,7 @@ func (s *storageDir) ContainerRestore(container container, sourceContainer conta
 		return err
 	}
 
-	shared.LogDebugf("Restored DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restored DIR storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return nil
 }
 
@@ -555,7 +556,7 @@ func (s *storageDir) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
-	shared.LogDebugf("Creating DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
@@ -593,11 +594,11 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 	if sourceContainer.IsRunning() {
 		// This is done to ensure consistency when snapshotting. But we
 		// probably shouldn't fail just because of that.
-		shared.LogDebugf("Trying to freeze and rsync again to ensure consistency.")
+		logger.Debugf("Trying to freeze and rsync again to ensure consistency.")
 
 		err := sourceContainer.Freeze()
 		if err != nil {
-			shared.LogErrorf("Trying to freeze and rsync again failed.")
+			logger.Errorf("Trying to freeze and rsync again failed.")
 			return nil
 		}
 
@@ -621,12 +622,12 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 		}
 	}
 
-	shared.LogDebugf("Created DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
-	shared.LogDebugf("Creating empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
@@ -659,12 +660,12 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 
 	revert = false
 
-	shared.LogDebugf("Created empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotDelete(snapshotContainer container) error {
-	shared.LogDebugf("Deleting DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -706,12 +707,12 @@ func (s *storageDir) ContainerSnapshotDelete(snapshotContainer container) error
 		}
 	}
 
-	shared.LogDebugf("Deleted DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted DIR storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageDir) ContainerSnapshotRename(snapshotContainer container, newName string) error {
-	shared.LogDebugf("Renaming DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	// Rename the mountpoint for the snapshot:
 	// ${POOL}/snapshots/<old_snapshot_name> to ${POOL}/snapshots/<new_snapshot_name>
@@ -722,7 +723,7 @@ func (s *storageDir) ContainerSnapshotRename(snapshotContainer container, newNam
 		return err
 	}
 
-	shared.LogDebugf("Renamed DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed DIR storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index afe56b7..8d41d34 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func storageVGActivate(lvmVolumePath string) error {
@@ -335,7 +336,7 @@ func (s *storageLvm) StorageCoreInit() error {
 		s.sTypeVersion += strings.TrimSpace(fields[1])
 	}
 
-	shared.LogDebugf("Initializing an LVM driver.")
+	logger.Debugf("Initializing an LVM driver.")
 	return nil
 }
 
@@ -367,7 +368,7 @@ func (s *storageLvm) StoragePoolInit() error {
 }
 
 func (s *storageLvm) StoragePoolCheck() error {
-	shared.LogDebugf("Checking LVM storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checking LVM storage pool \"%s\".", s.pool.Name)
 
 	_, err := s.StoragePoolMount()
 	if err != nil {
@@ -384,7 +385,7 @@ func (s *storageLvm) StoragePoolCheck() error {
 		return err
 	}
 
-	shared.LogDebugf("Checked LVM storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checked LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -431,7 +432,7 @@ func lvmVersionIsAtLeast(sTypeVersion string, versionString string) (bool, error
 }
 
 func (s *storageLvm) StoragePoolCreate() error {
-	shared.LogInfof("Creating LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Creating LVM storage pool \"%s\".", s.pool.Name)
 	tryUndo := true
 
 	// Create the mountpoint for the storage pool.
@@ -508,7 +509,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 
 		msg, err := shared.TryRunCommand("pvscan", "--cache")
 		if err != nil {
-			shared.LogWarnf("Failed to run pvscan: %s.", msg)
+			logger.Warnf("Failed to run pvscan: %s.", msg)
 		}
 
 		// Check if the volume group already exists.
@@ -523,7 +524,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 
 		msg, err = shared.TryRunCommand("vgscan", "--cache")
 		if err != nil {
-			shared.LogWarnf("Failed to run vgscan: %s.", msg)
+			logger.Warnf("Failed to run vgscan: %s.", msg)
 		}
 	} else {
 		s.pool.Config["size"] = ""
@@ -556,7 +557,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 
 			msg, err := shared.TryRunCommand("pvscan")
 			if err != nil {
-				shared.LogWarnf("Failed to run pvscan: %s.", msg)
+				logger.Warnf("Failed to run pvscan: %s.", msg)
 			}
 
 			// Check if the volume group already exists.
@@ -571,7 +572,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 
 			msg, err = shared.TryRunCommand("vgscan")
 			if err != nil {
-				shared.LogWarnf("Failed to run vgscan: %s.", msg)
+				logger.Warnf("Failed to run vgscan: %s.", msg)
 			}
 		} else {
 			if s.pool.Config["lvm.vg_name"] != "" {
@@ -600,12 +601,12 @@ func (s *storageLvm) StoragePoolCreate() error {
 	// Deregister cleanup.
 	tryUndo = false
 
-	shared.LogInfof("Created LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Created LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolDelete() error {
-	shared.LogInfof("Deleting LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleting LVM storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -633,7 +634,7 @@ func (s *storageLvm) StoragePoolDelete() error {
 		// otherwise we will get EBADF.
 		err = setAutoclearOnLoopDev(int(s.loopInfo.Fd()))
 		if err != nil {
-			shared.LogWarnf("Failed to set LO_FLAGS_AUTOCLEAR on loop device: %s. Manual cleanup needed.", err)
+			logger.Warnf("Failed to set LO_FLAGS_AUTOCLEAR on loop device: %s. Manual cleanup needed.", err)
 		}
 	}
 
@@ -653,7 +654,7 @@ func (s *storageLvm) StoragePoolDelete() error {
 		return err
 	}
 
-	shared.LogInfof("Deleted LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleted LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -675,7 +676,7 @@ func (s *storageLvm) StoragePoolMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage pool.
@@ -718,7 +719,7 @@ func (s *storageLvm) StoragePoolUmount() (bool, error) {
 }
 
 func (s *storageLvm) StoragePoolVolumeCreate() error {
-	shared.LogInfof("Creating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Creating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	tryUndo := true
 
 	poolName := s.getOnDiskPoolName()
@@ -741,7 +742,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 
 	err = lvmCreateThinLV(poolName, thinPoolName, s.volume.Name, lvFsType, lvSize, volumeType)
 	if err != nil {
-		shared.LogErrorf("LVMCreateThinLV: %s.", err)
+		logger.Errorf("LVMCreateThinLV: %s.", err)
 		return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
 	}
 	defer func() {
@@ -763,12 +764,12 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 
 	tryUndo = false
 
-	shared.LogInfof("Created LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Created LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeDelete() error {
-	shared.LogInfof("Deleting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	_, err := s.StoragePoolVolumeUmount()
@@ -794,12 +795,12 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	shared.LogInfof("Deleted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
-	shared.LogDebugf("Mounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	poolName := s.getOnDiskPoolName()
@@ -816,7 +817,7 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -844,12 +845,12 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 		return false, customerr
 	}
 
-	shared.LogDebugf("Mounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
-	shared.LogDebugf("Unmounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
@@ -858,7 +859,7 @@ func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -886,7 +887,7 @@ func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
 		return false, customerr
 	}
 
-	shared.LogDebugf("Unmounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounted LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -911,7 +912,7 @@ func (s *storageLvm) GetContainerPoolInfo() (int64, string) {
 }
 
 func (s *storageLvm) StoragePoolUpdate(writable *api.StoragePoolPut, changedConfig []string) error {
-	shared.LogInfof("Updating LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Updating LVM storage pool \"%s\".", s.pool.Name)
 
 	if shared.StringInSlice("size", changedConfig) {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
@@ -966,7 +967,7 @@ func (s *storageLvm) StoragePoolUpdate(writable *api.StoragePoolPut, changedConf
 
 			err = lvmLVRename(poolName, newThinpoolName, oldThinpoolName)
 			if err != nil {
-				shared.LogWarnf("Failed to rename LVM thinpool from \"%s\" to \"%s\": %s. Manual intervention needed.",
+				logger.Warnf("Failed to rename LVM thinpool from \"%s\" to \"%s\": %s. Manual intervention needed.",
 					newThinpoolName,
 					oldThinpoolName,
 					err)
@@ -1000,7 +1001,7 @@ func (s *storageLvm) StoragePoolUpdate(writable *api.StoragePoolPut, changedConf
 
 			err := lvmVGRename(newName, oldPoolName)
 			if err != nil {
-				shared.LogWarnf("Failed to rename LVM volume group from \"%s\" to \"%s\": %s. Manual intervention needed.",
+				logger.Warnf("Failed to rename LVM volume group from \"%s\" to \"%s\": %s. Manual intervention needed.",
 					newName,
 					oldPoolName)
 			}
@@ -1011,12 +1012,12 @@ func (s *storageLvm) StoragePoolUpdate(writable *api.StoragePoolPut, changedConf
 	// Update succeeded.
 	revert = false
 
-	shared.LogInfof("Updated LVM storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Updated LVM storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) StoragePoolVolumeUpdate(changedConfig []string) error {
-	shared.LogInfof("Updating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Updating LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	if shared.StringInSlice("block.mount_options", changedConfig) && len(changedConfig) == 1 {
 		// noop
@@ -1024,7 +1025,7 @@ func (s *storageLvm) StoragePoolVolumeUpdate(changedConfig []string) error {
 		return fmt.Errorf("The properties \"%v\" cannot be changed.", changedConfig)
 	}
 
-	shared.LogInfof("Updated LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Updated LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -1037,7 +1038,7 @@ func (s *storageLvm) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageLvm) ContainerCreate(container container) error {
-	shared.LogDebugf("Creating empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	tryUndo := true
 
@@ -1095,12 +1096,12 @@ func (s *storageLvm) ContainerCreate(container container) error {
 
 	tryUndo = false
 
-	shared.LogDebugf("Created empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint string) error {
-	shared.LogDebugf("Creating LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	tryUndo := true
 
@@ -1114,7 +1115,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -1196,13 +1197,13 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 
 	err = container.TemplateApply("create")
 	if err != nil {
-		shared.LogErrorf("Error in create template during ContainerCreateFromImage, continuing to unmount: %s.", err)
+		logger.Errorf("Error in create template during ContainerCreateFromImage, continuing to unmount: %s.", err)
 		return err
 	}
 
 	tryUndo = false
 
-	shared.LogDebugf("Created LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -1211,7 +1212,7 @@ func (s *storageLvm) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageLvm) ContainerDelete(container container) error {
-	shared.LogDebugf("Deleting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerName := container.Name()
 	containerLvmName := containerNameToLVName(containerName)
@@ -1254,7 +1255,7 @@ func (s *storageLvm) ContainerDelete(container container) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -1267,7 +1268,7 @@ func (s *storageLvm) copyContainer(target container, source container) error {
 
 	err = s.createSnapshotContainer(target, source, false)
 	if err != nil {
-		shared.LogErrorf("Error creating snapshot LV for copy: %s.", err)
+		logger.Errorf("Error creating snapshot LV for copy: %s.", err)
 		return err
 	}
 
@@ -1296,7 +1297,7 @@ func (s *storageLvm) copySnapshot(target container, source container) error {
 
 	err = s.createSnapshotContainer(target, source, true)
 	if err != nil {
-		shared.LogErrorf("Error creating snapshot LV for copy: %s.", err)
+		logger.Errorf("Error creating snapshot LV for copy: %s.", err)
 		return err
 	}
 
@@ -1304,7 +1305,7 @@ func (s *storageLvm) copySnapshot(target container, source container) error {
 }
 
 func (s *storageLvm) ContainerCopy(target container, source container, containerOnly bool) error {
-	shared.LogDebugf("Copying LVM container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copying LVM container storage %s -> %s.", source.Name(), target.Name())
 
 	ourStart, err := source.StorageStart()
 	if err != nil {
@@ -1326,7 +1327,7 @@ func (s *storageLvm) ContainerCopy(target container, source container, container
 	}
 
 	if containerOnly {
-		shared.LogDebugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -1336,7 +1337,7 @@ func (s *storageLvm) ContainerCopy(target container, source container, container
 	}
 
 	if len(snapshots) == 0 {
-		shared.LogDebugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
+		logger.Debugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
 		return nil
 	}
 
@@ -1359,12 +1360,12 @@ func (s *storageLvm) ContainerCopy(target container, source container, container
 		}
 	}
 
-	shared.LogDebugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copied LVM container storage %s -> %s.", source.Name(), target.Name())
 	return nil
 }
 
 func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
-	shared.LogDebugf("Mounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerLvmName := containerNameToLVName(name)
 	lvFsType := s.getLvmFilesystem()
@@ -1382,7 +1383,7 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -1410,12 +1411,12 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
 		return false, mounterr
 	}
 
-	shared.LogDebugf("Mounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
-	shared.LogDebugf("Unmounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerMntPoint := getContainerMountPoint(s.pool.Name, name)
 	if shared.IsSnapshot(name) {
@@ -1427,7 +1428,7 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -1455,12 +1456,12 @@ func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
-	shared.LogDebugf("Unmounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounted LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
 func (s *storageLvm) ContainerRename(container container, newContainerName string) error {
-	shared.LogDebugf("Renaming LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+	logger.Debugf("Renaming LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 
 	tryUndo := true
 
@@ -1536,12 +1537,12 @@ func (s *storageLvm) ContainerRename(container container, newContainerName strin
 
 	tryUndo = false
 
-	shared.LogDebugf("Renamed LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+	logger.Debugf("Renamed LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 	return nil
 }
 
 func (s *storageLvm) ContainerRestore(container container, sourceContainer container) error {
-	shared.LogDebugf("Restoring LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restoring LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 
 	ourStart, err := sourceContainer.StorageStart()
 	if err != nil {
@@ -1573,7 +1574,7 @@ func (s *storageLvm) ContainerRestore(container container, sourceContainer conta
 	poolName := s.getOnDiskPoolName()
 	err = s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, destLvName)
 	if err != nil {
-		shared.LogErrorf(fmt.Sprintf("Failed to remove \"%s\": %s.", destLvName, err))
+		logger.Errorf(fmt.Sprintf("Failed to remove \"%s\": %s.", destLvName, err))
 	}
 
 	_, err = s.createSnapshotLV(poolName, srcLvName, storagePoolVolumeApiEndpointContainers, destLvName, storagePoolVolumeApiEndpointContainers, false)
@@ -1581,7 +1582,7 @@ func (s *storageLvm) ContainerRestore(container container, sourceContainer conta
 		return fmt.Errorf("Error creating snapshot LV: %v", err)
 	}
 
-	shared.LogDebugf("Restored LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
+	logger.Debugf("Restored LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
 	return nil
 }
 
@@ -1594,14 +1595,14 @@ func (s *storageLvm) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
-	shared.LogDebugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	err := s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
 	if err != nil {
 		return err
 	}
 
-	shared.LogDebugf("Created LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -1612,7 +1613,7 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 	targetContainerName := snapshotContainer.Name()
 	sourceContainerLvmName := containerNameToLVName(sourceContainerName)
 	targetContainerLvmName := containerNameToLVName(targetContainerName)
-	shared.LogDebugf("Creating snapshot: %s -> %s.", sourceContainerName, targetContainerName)
+	logger.Debugf("Creating snapshot: %s -> %s.", sourceContainerName, targetContainerName)
 
 	poolName := s.getOnDiskPoolName()
 	_, err := s.createSnapshotLV(poolName, sourceContainerLvmName, storagePoolVolumeApiEndpointContainers, targetContainerLvmName, storagePoolVolumeApiEndpointContainers, readonly)
@@ -1649,19 +1650,19 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 }
 
 func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer container) error {
-	shared.LogDebugf("Deleting LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	err := s.ContainerDelete(snapshotContainer)
 	if err != nil {
 		return fmt.Errorf("Error deleting snapshot %s: %s", snapshotContainer.Name(), err)
 	}
 
-	shared.LogDebugf("Deleted LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newContainerName string) error {
-	shared.LogDebugf("Renaming LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+	logger.Debugf("Renaming LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 
 	tryUndo := true
 
@@ -1688,12 +1689,12 @@ func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newCon
 
 	tryUndo = false
 
-	shared.LogDebugf("Renamed LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
+	logger.Debugf("Renamed LVM storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newContainerName)
 	return nil
 }
 
 func (s *storageLvm) ContainerSnapshotStart(container container) (bool, error) {
-	shared.LogDebugf("Initializing LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initializing LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	tryUndo := true
 
@@ -1704,7 +1705,7 @@ func (s *storageLvm) ContainerSnapshotStart(container container) (bool, error) {
 
 	tmpTargetLvmName := getTmpSnapshotName(targetLvmName)
 
-	shared.LogDebugf("Creating snapshot: %s -> %s.", sourceLvmName, targetLvmName)
+	logger.Debugf("Creating snapshot: %s -> %s.", sourceLvmName, targetLvmName)
 
 	poolName := s.getOnDiskPoolName()
 	lvpath, err := s.createSnapshotLV(poolName, sourceLvmName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName, storagePoolVolumeApiEndpointContainers, false)
@@ -1739,12 +1740,12 @@ func (s *storageLvm) ContainerSnapshotStart(container container) (bool, error) {
 
 	tryUndo = false
 
-	shared.LogDebugf("Initialized LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initialized LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageLvm) ContainerSnapshotStop(container container) (bool, error) {
-	shared.LogDebugf("Stopping LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopping LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	name := container.Name()
 	snapshotMntPoint := getSnapshotMountPoint(s.pool.Name, name)
@@ -1765,24 +1766,24 @@ func (s *storageLvm) ContainerSnapshotStop(container container) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Stopped LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopped LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer container) error {
-	shared.LogDebugf("Creating empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	err := s.ContainerCreate(snapshotContainer)
 	if err != nil {
 		return err
 	}
 
-	shared.LogDebugf("Created empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ImageCreate(fingerprint string) error {
-	shared.LogDebugf("Creating LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Creating LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	tryUndo := true
 	trySubUndo := true
@@ -1805,7 +1806,7 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 		}
 		err := s.deleteImageDbPoolVolume(fingerprint)
 		if err != nil {
-			shared.LogWarnf("Could not delete image \"%s\" from storage volume database. Manual intervention needed.", fingerprint)
+			logger.Warnf("Could not delete image \"%s\" from storage volume database. Manual intervention needed.", fingerprint)
 		}
 	}()
 
@@ -1816,7 +1817,7 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 
 	err = lvmCreateThinLV(poolName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeApiEndpointImages)
 	if err != nil {
-		shared.LogErrorf("LVMCreateThinLV: %s.", err)
+		logger.Errorf("LVMCreateThinLV: %s.", err)
 		return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
 	}
 	trySubUndo = false
@@ -1850,12 +1851,12 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 
 	tryUndo = false
 
-	shared.LogDebugf("Created LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Created LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ImageDelete(fingerprint string) error {
-	shared.LogDebugf("Deleting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	_, err := s.ImageUmount(fingerprint)
 	if err != nil {
@@ -1881,12 +1882,12 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
 func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
-	shared.LogDebugf("Mounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Mounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	if shared.IsMountPoint(imageMntPoint) {
@@ -1904,16 +1905,16 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
 	lvmMountOptions := s.getLvmBlockMountOptions()
 	err := tryMount(lvmVolumePath, imageMntPoint, lvmFstype, 0, lvmMountOptions)
 	if err != nil {
-		shared.LogErrorf(fmt.Sprintf("Error mounting image LV for unpacking: %s", err))
+		logger.Errorf(fmt.Sprintf("Error mounting image LV for unpacking: %s", err))
 		return false, fmt.Errorf("Error mounting image LV: %v", err)
 	}
 
-	shared.LogDebugf("Mounted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Mounted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
-	shared.LogDebugf("Unmounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Unmounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.IsMountPoint(imageMntPoint) {
@@ -1925,7 +1926,7 @@ func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Unmounted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Unmounted LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return true, nil
 }
 
@@ -1953,7 +1954,7 @@ func createDefaultThinPool(sTypeVersion string, vgName string, thinPoolName stri
 	}
 
 	if err != nil {
-		shared.LogErrorf("Could not create thin pool \"%s\": %s.", thinPoolName, string(output))
+		logger.Errorf("Could not create thin pool \"%s\": %s.", thinPoolName, string(output))
 		return fmt.Errorf("Could not create LVM thin pool named %s", thinPoolName)
 	}
 
@@ -1962,7 +1963,7 @@ func createDefaultThinPool(sTypeVersion string, vgName string, thinPoolName stri
 		output, err = shared.TryRunCommand("lvextend", "--alloc", "anywhere", "-l", "100%FREE", lvmThinPool)
 
 		if err != nil {
-			shared.LogErrorf("Could not grow thin pool: \"%s\": %s.", thinPoolName, string(output))
+			logger.Errorf("Could not grow thin pool: \"%s\": %s.", thinPoolName, string(output))
 			return fmt.Errorf("Could not grow LVM thin pool named %s", thinPoolName)
 		}
 	}
@@ -1987,7 +1988,7 @@ func lvmCreateThinpool(d *Daemon, sTypeVersion string, vgName string, thinPoolNa
 
 	err = storageLVMValidateThinPoolName(d, vgName, thinPoolName)
 	if err != nil {
-		shared.LogErrorf("Setting thin pool name: %s.", err)
+		logger.Errorf("Setting thin pool name: %s.", err)
 		return fmt.Errorf("Error setting LVM thin pool config: %v", err)
 	}
 
@@ -2003,7 +2004,7 @@ func lvmCreateThinLV(vgName string, thinPoolName string, lvName string, lvFsType
 		"-n", lvmPoolVolumeName,
 		"--virtualsize", lvSize+"B", lvmThinPoolPath)
 	if err != nil {
-		shared.LogErrorf("Could not create LV \"%s\": %s.", lvmPoolVolumeName, output)
+		logger.Errorf("Could not create LV \"%s\": %s.", lvmPoolVolumeName, output)
 		return fmt.Errorf("Could not create thin LV named %s", lvmPoolVolumeName)
 	}
 
@@ -2020,7 +2021,7 @@ func lvmCreateThinLV(vgName string, thinPoolName string, lvName string, lvFsType
 	}
 
 	if err != nil {
-		shared.LogErrorf("Filesystem creation failed: %s.", output)
+		logger.Errorf("Filesystem creation failed: %s.", output)
 		return fmt.Errorf("Error making filesystem on image LV: %v", err)
 	}
 
@@ -2032,7 +2033,7 @@ func (s *storageLvm) removeLV(vgName string, volumeType string, lvName string) e
 	output, err := shared.TryRunCommand("lvremove", "-f", lvmVolumePath)
 
 	if err != nil {
-		shared.LogErrorf("Could not remove LV \"%s\": %s.", lvName, output)
+		logger.Errorf("Could not remove LV \"%s\": %s.", lvName, output)
 		return fmt.Errorf("Could not remove LV named %s", lvName)
 	}
 
@@ -2041,7 +2042,7 @@ func (s *storageLvm) removeLV(vgName string, volumeType string, lvName string) e
 
 func (s *storageLvm) createSnapshotLV(vgName string, origLvName string, origVolumeType string, lvName string, volumeType string, readonly bool) (string, error) {
 	sourceLvmVolumePath := getLvmDevPath(vgName, origVolumeType, origLvName)
-	shared.LogDebugf("in createSnapshotLV: %s.", sourceLvmVolumePath)
+	logger.Debugf("in createSnapshotLV: %s.", sourceLvmVolumePath)
 	isRecent, err := lvmVersionIsAtLeast(s.sTypeVersion, "2.02.99")
 	if err != nil {
 		return "", fmt.Errorf("Error checking LVM version: %v", err)
@@ -2062,7 +2063,7 @@ func (s *storageLvm) createSnapshotLV(vgName string, origLvName string, origVolu
 			"-s", sourceLvmVolumePath)
 	}
 	if err != nil {
-		shared.LogErrorf("Could not create LV snapshot: %s -> %s: %s.", origLvName, lvName, output)
+		logger.Errorf("Could not create LV snapshot: %s -> %s: %s.", origLvName, lvName, output)
 		return "", fmt.Errorf("Could not create snapshot LV named %s", lvName)
 	}
 
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 5d48e4f..9fc7759 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type storageMock struct {
@@ -21,7 +22,7 @@ func (s *storageMock) StorageCoreInit() error {
 	}
 	s.sTypeName = typeName
 
-	shared.LogDebugf("Initializing a MOCK driver.")
+	logger.Debugf("Initializing a MOCK driver.")
 	return nil
 }
 
@@ -35,19 +36,19 @@ func (s *storageMock) StoragePoolInit() error {
 }
 
 func (s *storageMock) StoragePoolCheck() error {
-	shared.LogDebugf("Checking MOCK storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checking MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageMock) StoragePoolCreate() error {
-	shared.LogInfof("Creating MOCK storage pool \"%s\".", s.pool.Name)
-	shared.LogInfof("Created MOCK storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Creating MOCK storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Created MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageMock) StoragePoolDelete() error {
-	shared.LogInfof("Deleting MOCK storage pool \"%s\".", s.pool.Name)
-	shared.LogInfof("Deleted MOCK storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleting MOCK storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleted MOCK storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
index 64bb980..6961e68 100644
--- a/lxd/storage_shared.go
+++ b/lxd/storage_shared.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type storageShared struct {
@@ -36,7 +37,7 @@ func (s *storageShared) shiftRootfs(c container) error {
 	dpath := c.Path()
 	rpath := c.RootfsPath()
 
-	shared.LogDebugf("Shifting root filesystem \"%s\" for \"%s\".", rpath, c.Name())
+	logger.Debugf("Shifting root filesystem \"%s\" for \"%s\".", rpath, c.Name())
 
 	idmapset, err := c.IdmapSet()
 	if err != nil {
@@ -49,7 +50,7 @@ func (s *storageShared) shiftRootfs(c container) error {
 
 	err = idmapset.ShiftRootfs(rpath)
 	if err != nil {
-		shared.LogDebugf("Shift of rootfs %s failed: %s", rpath, err)
+		logger.Debugf("Shift of rootfs %s failed: %s", rpath, err)
 		return err
 	}
 
@@ -89,7 +90,7 @@ func (s *storageShared) setUnprivUserAcl(c container, destPath string) error {
 	// Fallback to chmod if the fs doesn't support it.
 	_, err = shared.RunCommand("chmod", "+x", destPath)
 	if err != nil {
-		shared.LogDebugf("Failed to set executable bit on the container path: %s", err)
+		logger.Debugf("Failed to set executable bit on the container path: %s", err)
 		return err
 	}
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index a1f4fea..e56491f 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -16,6 +16,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 
 	"github.com/pborman/uuid"
 )
@@ -74,7 +75,7 @@ func (s *storageZfs) StorageCoreInit() error {
 		return err
 	}
 
-	shared.LogDebugf("Initializing a ZFS driver.")
+	logger.Debugf("Initializing a ZFS driver.")
 	return nil
 }
 
@@ -94,7 +95,7 @@ func (s *storageZfs) StoragePoolInit() error {
 }
 
 func (s *storageZfs) StoragePoolCheck() error {
-	shared.LogDebugf("Checking ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Debugf("Checking ZFS storage pool \"%s\".", s.pool.Name)
 
 	source := s.pool.Config["source"]
 	if source == "" {
@@ -106,7 +107,7 @@ func (s *storageZfs) StoragePoolCheck() error {
 		if zfsFilesystemEntityExists(poolName) {
 			return nil
 		}
-		shared.LogDebugf("ZFS storage pool \"%s\" does not exist. Trying to import it.", poolName)
+		logger.Debugf("ZFS storage pool \"%s\" does not exist. Trying to import it.", poolName)
 
 		disksPath := shared.VarPath("disks")
 		output, err := shared.RunCommand(
@@ -117,14 +118,14 @@ func (s *storageZfs) StoragePoolCheck() error {
 			return fmt.Errorf("ZFS storage pool \"%s\" could not be imported: %s.", poolName, output)
 		}
 
-		shared.LogDebugf("ZFS storage pool \"%s\" successfully imported.", poolName)
+		logger.Debugf("ZFS storage pool \"%s\" successfully imported.", poolName)
 	}
 
 	return nil
 }
 
 func (s *storageZfs) StoragePoolCreate() error {
-	shared.LogInfof("Creating ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Creating ZFS storage pool \"%s\".", s.pool.Name)
 
 	err := s.zfsPoolCreate()
 	if err != nil {
@@ -151,12 +152,12 @@ func (s *storageZfs) StoragePoolCreate() error {
 
 	revert = false
 
-	shared.LogInfof("Created ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Created ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolDelete() error {
-	shared.LogInfof("Deleting ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleting ZFS storage pool \"%s\".", s.pool.Name)
 
 	err := s.zfsFilesystemEntityDelete()
 	if err != nil {
@@ -171,7 +172,7 @@ func (s *storageZfs) StoragePoolDelete() error {
 		}
 	}
 
-	shared.LogInfof("Deleted ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Deleted ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
@@ -184,7 +185,7 @@ func (s *storageZfs) StoragePoolUmount() (bool, error) {
 }
 
 func (s *storageZfs) StoragePoolVolumeCreate() error {
-	shared.LogInfof("Creating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Creating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
@@ -212,12 +213,12 @@ func (s *storageZfs) StoragePoolVolumeCreate() error {
 
 	revert = false
 
-	shared.LogInfof("Created ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Created ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeDelete() error {
-	shared.LogInfof("Deleting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
@@ -234,12 +235,12 @@ func (s *storageZfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	shared.LogInfof("Deleted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Deleted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
-	shared.LogDebugf("Mounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
@@ -249,7 +250,7 @@ func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -277,12 +278,12 @@ func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
 		return false, customerr
 	}
 
-	shared.LogDebugf("Mounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
-	shared.LogDebugf("Unmounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounting ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
@@ -292,7 +293,7 @@ func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[customUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -320,7 +321,7 @@ func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
 		return false, customerr
 	}
 
-	shared.LogDebugf("Unmounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounted ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -345,7 +346,7 @@ func (s *storageZfs) GetContainerPoolInfo() (int64, string) {
 }
 
 func (s *storageZfs) StoragePoolUpdate(writable *api.StoragePoolPut, changedConfig []string) error {
-	shared.LogInfof("Updating ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Updating ZFS storage pool \"%s\".", s.pool.Name)
 
 	if shared.StringInSlice("size", changedConfig) {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
@@ -379,12 +380,12 @@ func (s *storageZfs) StoragePoolUpdate(writable *api.StoragePoolPut, changedConf
 		return fmt.Errorf("The \"zfs.pool_name\" property cannot be changed.")
 	}
 
-	shared.LogInfof("Updated ZFS storage pool \"%s\".", s.pool.Name)
+	logger.Infof("Updated ZFS storage pool \"%s\".", s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) StoragePoolVolumeUpdate(changedConfig []string) error {
-	shared.LogInfof("Updating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Updating ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	if shared.StringInSlice("block.mount_options", changedConfig) {
 		return fmt.Errorf("The \"block.mount_options\" property cannot be changed.")
@@ -398,13 +399,13 @@ func (s *storageZfs) StoragePoolVolumeUpdate(changedConfig []string) error {
 		return fmt.Errorf("The \"size\" property cannot be changed.")
 	}
 
-	shared.LogInfof("Updated ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Infof("Updated ZFS storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 // Things we don't need to care about
 func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
-	shared.LogDebugf("Mounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
@@ -414,7 +415,7 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerMountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in mounting the storage volume.
@@ -442,12 +443,12 @@ func (s *storageZfs) ContainerMount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
-	shared.LogDebugf("Mounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Mounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourMount, nil
 }
 
 func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
-	shared.LogDebugf("Unmounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("containers/%s", name)
 	containerPoolVolumeMntPoint := getContainerMountPoint(s.pool.Name, name)
@@ -457,7 +458,7 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 	if waitChannel, ok := lxdStorageOngoingOperationMap[containerUmountLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 		// Give the benefit of the doubt and assume that the other
 		// thread actually succeeded in unmounting the storage volume.
@@ -485,7 +486,7 @@ func (s *storageZfs) ContainerUmount(name string, path string) (bool, error) {
 		return false, imgerr
 	}
 
-	shared.LogDebugf("Unmounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Unmounted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return ourUmount, nil
 }
 
@@ -497,7 +498,7 @@ func (s *storageZfs) ContainerStorageReady(name string) bool {
 }
 
 func (s *storageZfs) ContainerCreate(container container) error {
-	shared.LogDebugf("Creating empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerPath := container.Path()
 	containerName := container.Name()
@@ -535,12 +536,12 @@ func (s *storageZfs) ContainerCreate(container container) error {
 
 	revert = false
 
-	shared.LogDebugf("Created empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created empty ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint string) error {
-	shared.LogDebugf("Creating ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Creating ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerPath := container.Path()
 	containerName := container.Name()
@@ -554,7 +555,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
 		lxdStorageMapLock.Unlock()
 		if _, ok := <-waitChannel; ok {
-			shared.LogWarnf("Received value over semaphore. This should not have happened.")
+			logger.Warnf("Received value over semaphore. This should not have happened.")
 		}
 	} else {
 		lxdStorageOngoingOperationMap[imageStoragePoolLockID] = make(chan bool)
@@ -609,7 +610,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 
 	revert = false
 
-	shared.LogDebugf("Created ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Created ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -637,7 +638,7 @@ func (s *storageZfs) ContainerCanRestore(container container, sourceContainer co
 }
 
 func (s *storageZfs) ContainerDelete(container container) error {
-	shared.LogDebugf("Deleting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	containerName := container.Name()
 	fs := fmt.Sprintf("containers/%s", containerName)
@@ -719,7 +720,7 @@ func (s *storageZfs) ContainerDelete(container container) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted ZFS storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
@@ -824,7 +825,7 @@ func (s *storageZfs) copyWithoutSnapshotsSparse(target container, source contain
 }
 
 func (s *storageZfs) copyWithoutSnapshotFull(target container, source container) error {
-	shared.LogDebugf("Creating full ZFS copy \"%s\" -> \"%s\".", source.Name(), target.Name())
+	logger.Debugf("Creating full ZFS copy \"%s\" -> \"%s\".", source.Name(), target.Name())
 
 	sourceIsSnapshot := source.IsSnapshot()
 	poolName := s.getOnDiskPoolName()
@@ -855,7 +856,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 		defer func() {
 			err := s.zfsPoolVolumeSnapshotDestroy(fs, snapshotSuffix)
 			if err != nil {
-				shared.LogWarnf("Failed to delete temporary ZFS snapshot \"%s\". Manual cleanup needed.", sourceDataset)
+				logger.Warnf("Failed to delete temporary ZFS snapshot \"%s\". Manual cleanup needed.", sourceDataset)
 			}
 		}()
 	}
@@ -885,7 +886,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 
 	msg, err := shared.RunCommand("zfs", "rollback", "-r", "-R", targetSnapshotDataset)
 	if err != nil {
-		shared.LogErrorf("Failed to rollback ZFS dataset: %s.", msg)
+		logger.Errorf("Failed to rollback ZFS dataset: %s.", msg)
 		return err
 	}
 
@@ -906,7 +907,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 		return err
 	}
 
-	shared.LogDebugf("Created full ZFS copy \"%s\" -> \"%s\".", source.Name(), target.Name())
+	logger.Debugf("Created full ZFS copy \"%s\" -> \"%s\".", source.Name(), target.Name())
 	return nil
 }
 
@@ -958,7 +959,7 @@ func (s *storageZfs) copyWithSnapshots(target container, source container, paren
 }
 
 func (s *storageZfs) ContainerCopy(target container, source container, containerOnly bool) error {
-	shared.LogDebugf("Copying ZFS container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copying ZFS container storage %s -> %s.", source.Name(), target.Name())
 
 	ourStart, err := source.StorageStart()
 	if err != nil {
@@ -1026,12 +1027,12 @@ func (s *storageZfs) ContainerCopy(target container, source container, container
 
 	}
 
-	shared.LogDebugf("Copied ZFS container storage %s -> %s.", source.Name(), target.Name())
+	logger.Debugf("Copied ZFS container storage %s -> %s.", source.Name(), target.Name())
 	return nil
 }
 
 func (s *storageZfs) ContainerRename(container container, newName string) error {
-	shared.LogDebugf("Renaming ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	oldName := container.Name()
 
@@ -1108,12 +1109,12 @@ func (s *storageZfs) ContainerRename(container container, newName string) error
 
 	revert = false
 
-	shared.LogDebugf("Renamed ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageZfs) ContainerRestore(target container, source container) error {
-	shared.LogDebugf("Restoring ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, source.Name(), target.Name())
+	logger.Debugf("Restoring ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, source.Name(), target.Name())
 
 	// Start storage for source container
 	ourSourceStart, err := source.StorageStart()
@@ -1160,12 +1161,12 @@ func (s *storageZfs) ContainerRestore(target container, source container) error
 		return err
 	}
 
-	shared.LogDebugf("Restored ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, source.Name(), target.Name())
+	logger.Debugf("Restored ZFS storage volume for container \"%s\" from %s -> %s.", s.volume.Name, source.Name(), target.Name())
 	return nil
 }
 
 func (s *storageZfs) ContainerSetQuota(container container, size int64) error {
-	shared.LogDebugf("Setting ZFS quota for container \"%s\".", container.Name())
+	logger.Debugf("Setting ZFS quota for container \"%s\".", container.Name())
 
 	var err error
 
@@ -1194,7 +1195,7 @@ func (s *storageZfs) ContainerSetQuota(container container, size int64) error {
 		return err
 	}
 
-	shared.LogDebugf("Set ZFS quota for container \"%s\".", container.Name())
+	logger.Debugf("Set ZFS quota for container \"%s\".", container.Name())
 	return nil
 }
 
@@ -1231,7 +1232,7 @@ func (s *storageZfs) ContainerGetUsage(container container) (int64, error) {
 
 func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
 	snapshotContainerName := snapshotContainer.Name()
-	shared.LogDebugf("Creating ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", snapshotContainerName, s.pool.Name)
+	logger.Debugf("Creating ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", snapshotContainerName, s.pool.Name)
 
 	sourceContainerName := sourceContainer.Name()
 
@@ -1271,12 +1272,12 @@ func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer container, source
 
 	revert = false
 
-	shared.LogDebugf("Created ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", snapshotContainerName, s.pool.Name)
+	logger.Debugf("Created ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", snapshotContainerName, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer container) error {
-	shared.LogDebugf("Deleting ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleting ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fields := strings.SplitN(snapshotContainer.Name(), shared.SnapshotDelimiter, 2)
 	sourceContainerName := fields[0]
@@ -1348,12 +1349,12 @@ func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer container) error
 		}
 	}
 
-	shared.LogDebugf("Deleted ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Deleted ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newName string) error {
-	shared.LogDebugf("Renaming ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renaming ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 
 	oldName := snapshotContainer.Name()
 
@@ -1413,12 +1414,12 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 
 	revert = false
 
-	shared.LogDebugf("Renamed ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
+	logger.Debugf("Renamed ZFS storage volume for snapshot \"%s\" from %s -> %s.", s.volume.Name, s.volume.Name, newName)
 	return nil
 }
 
 func (s *storageZfs) ContainerSnapshotStart(container container) (bool, error) {
-	shared.LogDebugf("Initializing ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initializing ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fields := strings.SplitN(container.Name(), shared.SnapshotDelimiter, 2)
 	if len(fields) < 2 {
@@ -1437,12 +1438,12 @@ func (s *storageZfs) ContainerSnapshotStart(container container) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Initialized ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Initialized ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
 func (s *storageZfs) ContainerSnapshotStop(container container) (bool, error) {
-	shared.LogDebugf("Stopping ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopping ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 
 	fields := strings.SplitN(container.Name(), shared.SnapshotDelimiter, 2)
 	if len(fields) < 2 {
@@ -1457,7 +1458,7 @@ func (s *storageZfs) ContainerSnapshotStop(container container) (bool, error) {
 		return false, err
 	}
 
-	shared.LogDebugf("Stopped ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+	logger.Debugf("Stopped ZFS storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
 	return true, nil
 }
 
@@ -1474,7 +1475,7 @@ func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 // - remove mountpoint property from zfs volume images/<fingerprint>
 // - create read-write snapshot from zfs volume images/<fingerprint>
 func (s *storageZfs) ImageCreate(fingerprint string) error {
-	shared.LogDebugf("Creating ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Creating ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
 	fs := fmt.Sprintf("images/%s", fingerprint)
@@ -1597,12 +1598,12 @@ func (s *storageZfs) ImageCreate(fingerprint string) error {
 
 	revert = false
 
-	shared.LogDebugf("Created ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Created ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
 func (s *storageZfs) ImageDelete(fingerprint string) error {
-	shared.LogDebugf("Deleting ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleting ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 
 	fs := fmt.Sprintf("images/%s", fingerprint)
 
@@ -1650,7 +1651,7 @@ func (s *storageZfs) ImageDelete(fingerprint string) error {
 		}
 	}
 
-	shared.LogDebugf("Deleted ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+	logger.Debugf("Deleted ZFS storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
 	return nil
 }
 
@@ -1762,7 +1763,7 @@ func (s *storageZfs) zfsPoolCreate() error {
 						"mountpoint=none",
 						vdev)
 					if err != nil {
-						shared.LogErrorf("zfs create failed: %s.", output)
+						logger.Errorf("zfs create failed: %s.", output)
 						return fmt.Errorf("Failed to create ZFS filesystem: %s", output)
 					}
 				}
@@ -1839,7 +1840,7 @@ func (s *storageZfs) zfsPoolVolumeClone(source string, name string, dest string,
 		fmt.Sprintf("%s/%s@%s", poolName, source, name),
 		fmt.Sprintf("%s/%s", poolName, dest))
 	if err != nil {
-		shared.LogErrorf("zfs clone failed: %s.", output)
+		logger.Errorf("zfs clone failed: %s.", output)
 		return fmt.Errorf("Failed to clone the filesystem: %s", output)
 	}
 
@@ -1869,7 +1870,7 @@ func (s *storageZfs) zfsPoolVolumeClone(source string, name string, dest string,
 			fmt.Sprintf("%s/%s@%s", poolName, sub, name),
 			fmt.Sprintf("%s/%s", poolName, destSubvol))
 		if err != nil {
-			shared.LogErrorf("zfs clone failed: %s.", output)
+			logger.Errorf("zfs clone failed: %s.", output)
 			return fmt.Errorf("Failed to clone the sub-volume: %s", output)
 		}
 	}
@@ -1885,7 +1886,7 @@ func (s *storageZfs) zfsPoolVolumeCreate(path string) error {
 		"-p",
 		fmt.Sprintf("%s/%s", poolName, path))
 	if err != nil {
-		shared.LogErrorf("zfs create failed: %s.", output)
+		logger.Errorf("zfs create failed: %s.", output)
 		return fmt.Errorf("Failed to create ZFS filesystem: %s", output)
 	}
 
@@ -1925,7 +1926,7 @@ func (s *storageZfs) zfsPoolVolumeDestroy(path string) error {
 	if mountpoint != "none" && shared.IsMountPoint(mountpoint) {
 		err := syscall.Unmount(mountpoint, syscall.MNT_DETACH)
 		if err != nil {
-			shared.LogErrorf("umount failed: %s.", err)
+			logger.Errorf("umount failed: %s.", err)
 			return err
 		}
 	}
@@ -1939,7 +1940,7 @@ func (s *storageZfs) zfsPoolVolumeDestroy(path string) error {
 		fmt.Sprintf("%s/%s", poolName, path))
 
 	if err != nil {
-		shared.LogErrorf("zfs destroy failed: %s.", output)
+		logger.Errorf("zfs destroy failed: %s.", output)
 		return fmt.Errorf("Failed to destroy ZFS filesystem: %s", output)
 	}
 
@@ -2078,7 +2079,7 @@ func (s *storageZfs) zfsPoolVolumeRename(source string, dest string) error {
 	}
 
 	// Timeout
-	shared.LogErrorf("zfs rename failed: %s.", output)
+	logger.Errorf("zfs rename failed: %s.", output)
 	return fmt.Errorf("Failed to rename ZFS filesystem: %s", output)
 }
 
@@ -2090,7 +2091,7 @@ func (s *storageZfs) zfsPoolVolumeSet(path string, key string, value string) err
 		fmt.Sprintf("%s=%s", key, value),
 		fmt.Sprintf("%s/%s", poolName, path))
 	if err != nil {
-		shared.LogErrorf("zfs set failed: %s.", output)
+		logger.Errorf("zfs set failed: %s.", output)
 		return fmt.Errorf("Failed to set ZFS config: %s", output)
 	}
 
@@ -2105,7 +2106,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotCreate(path string, name string) error
 		"-r",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name))
 	if err != nil {
-		shared.LogErrorf("zfs snapshot failed: %s.", output)
+		logger.Errorf("zfs snapshot failed: %s.", output)
 		return fmt.Errorf("Failed to create ZFS snapshot: %s", output)
 	}
 
@@ -2120,7 +2121,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotDestroy(path string, name string) erro
 		"-r",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name))
 	if err != nil {
-		shared.LogErrorf("zfs destroy failed: %s.", output)
+		logger.Errorf("zfs destroy failed: %s.", output)
 		return fmt.Errorf("Failed to destroy ZFS snapshot: %s", output)
 	}
 
@@ -2134,7 +2135,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRestore(path string, name string) erro
 		"rollback",
 		fmt.Sprintf("%s/%s@%s", poolName, path, name))
 	if err != nil {
-		shared.LogErrorf("zfs rollback failed: %s.", output)
+		logger.Errorf("zfs rollback failed: %s.", output)
 		return fmt.Errorf("Failed to restore ZFS snapshot: %s", output)
 	}
 
@@ -2158,7 +2159,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRestore(path string, name string) erro
 			"rollback",
 			fmt.Sprintf("%s/%s@%s", poolName, sub, name))
 		if err != nil {
-			shared.LogErrorf("zfs rollback failed: %s.", output)
+			logger.Errorf("zfs rollback failed: %s.", output)
 			return fmt.Errorf("Failed to restore ZFS sub-volume snapshot: %s", output)
 		}
 	}
@@ -2175,7 +2176,7 @@ func (s *storageZfs) zfsPoolVolumeSnapshotRename(path string, oldName string, ne
 		fmt.Sprintf("%s/%s@%s", poolName, path, oldName),
 		fmt.Sprintf("%s/%s@%s", poolName, path, newName))
 	if err != nil {
-		shared.LogErrorf("zfs snapshot rename failed: %s.", output)
+		logger.Errorf("zfs snapshot rename failed: %s.", output)
 		return fmt.Errorf("Failed to rename ZFS snapshot: %s", output)
 	}
 
@@ -2204,10 +2205,10 @@ func zfsUmount(poolName string, path string, mountpoint string) error {
 		"unmount",
 		fmt.Sprintf("%s/%s", poolName, path))
 	if err != nil {
-		shared.LogWarnf("Failed to unmount ZFS filesystem via zfs unmount: %s. Trying lazy umount (MNT_DETACH)...", output)
+		logger.Warnf("Failed to unmount ZFS filesystem via zfs unmount: %s. Trying lazy umount (MNT_DETACH)...", output)
 		err := tryUnmount(mountpoint, syscall.MNT_DETACH)
 		if err != nil {
-			shared.LogWarnf("Failed to unmount ZFS filesystem via lazy umount (MNT_DETACH)...")
+			logger.Warnf("Failed to unmount ZFS filesystem via lazy umount (MNT_DETACH)...")
 			return err
 		}
 	}
@@ -2228,7 +2229,7 @@ func (s *storageZfs) zfsPoolListSubvolumes(path string) ([]string, error) {
 		"-H",
 		"-r", path)
 	if err != nil {
-		shared.LogErrorf("zfs list failed: %s.", output)
+		logger.Errorf("zfs list failed: %s.", output)
 		return []string{}, fmt.Errorf("Failed to list ZFS filesystems: %s", output)
 	}
 
@@ -2267,7 +2268,7 @@ func (s *storageZfs) zfsPoolListSnapshots(path string) ([]string, error) {
 		"-s", "creation",
 		"-r", fullPath)
 	if err != nil {
-		shared.LogErrorf("zfs list failed: %s.", output)
+		logger.Errorf("zfs list failed: %s.", output)
 		return []string{}, fmt.Errorf("Failed to list ZFS snapshots: %s", output)
 	}
 
@@ -2409,12 +2410,12 @@ func (s *zfsMigrationSourceDriver) send(conn *websocket.Conn, zfsName string, zf
 
 	output, err := ioutil.ReadAll(stderr)
 	if err != nil {
-		shared.LogErrorf("Problem reading zfs send stderr: %s.", err)
+		logger.Errorf("Problem reading zfs send stderr: %s.", err)
 	}
 
 	err = cmd.Wait()
 	if err != nil {
-		shared.LogErrorf("Problem with zfs send: %s.", string(output))
+		logger.Errorf("Problem with zfs send: %s.", string(output))
 	}
 
 	return err
@@ -2565,12 +2566,12 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 
 		output, err := ioutil.ReadAll(stderr)
 		if err != nil {
-			shared.LogDebugf("problem reading zfs recv stderr %s.", err)
+			logger.Debugf("problem reading zfs recv stderr %s.", err)
 		}
 
 		err = cmd.Wait()
 		if err != nil {
-			shared.LogErrorf("problem with zfs recv: %s.", string(output))
+			logger.Errorf("problem with zfs recv: %s.", string(output))
 		}
 		return err
 	}
@@ -2652,7 +2653,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		/* clean up our migration-send snapshots that we got from recv. */
 		zfsSnapshots, err := s.zfsPoolListSnapshots(fmt.Sprintf("containers/%s", container.Name()))
 		if err != nil {
-			shared.LogErrorf("failed listing snapshots post migration: %s.", err)
+			logger.Errorf("failed listing snapshots post migration: %s.", err)
 			return
 		}
 
diff --git a/shared/json.go b/shared/json.go
index 644d0f7..09f1066 100644
--- a/shared/json.go
+++ b/shared/json.go
@@ -4,6 +4,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
+
+	"github.com/lxc/lxd/shared/logger"
 )
 
 type Jmap map[string]interface{}
@@ -51,11 +53,11 @@ func (m Jmap) GetBool(key string) (bool, error) {
 func DebugJson(r *bytes.Buffer) {
 	pretty := &bytes.Buffer{}
 	if err := json.Indent(pretty, r.Bytes(), "\t", "\t"); err != nil {
-		LogDebugf("error indenting json: %s", err)
+		logger.Debugf("error indenting json: %s", err)
 		return
 	}
 
 	// Print the JSON without the last "\n"
 	str := pretty.String()
-	LogDebugf("\n\t%s", str[0:len(str)-1])
+	logger.Debugf("\n\t%s", str[0:len(str)-1])
 }
diff --git a/shared/log.go b/shared/log.go
deleted file mode 100644
index ec464e0..0000000
--- a/shared/log.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// +build !logdebug
-
-package shared
-
-import (
-	"fmt"
-	"runtime"
-)
-
-type Logger interface {
-	Debug(msg string, ctx ...interface{})
-	Info(msg string, ctx ...interface{})
-	Warn(msg string, ctx ...interface{})
-	Error(msg string, ctx ...interface{})
-	Crit(msg string, ctx ...interface{})
-}
-
-var Log Logger
-
-type nullLogger struct{}
-
-func (nl nullLogger) Debug(msg string, ctx ...interface{}) {}
-func (nl nullLogger) Info(msg string, ctx ...interface{})  {}
-func (nl nullLogger) Warn(msg string, ctx ...interface{})  {}
-func (nl nullLogger) Error(msg string, ctx ...interface{}) {}
-func (nl nullLogger) Crit(msg string, ctx ...interface{})  {}
-
-func init() {
-	Log = nullLogger{}
-}
-
-// General wrappers around Logger interface functions.
-func LogDebug(msg string, ctx interface{}) {
-	if Log != nil {
-		Log.Debug(msg, ctx)
-	}
-}
-
-func LogInfo(msg string, ctx interface{}) {
-	if Log != nil {
-		Log.Info(msg, ctx)
-	}
-}
-
-func LogWarn(msg string, ctx interface{}) {
-	if Log != nil {
-		Log.Warn(msg, ctx)
-	}
-}
-
-func LogError(msg string, ctx interface{}) {
-	if Log != nil {
-		Log.Error(msg, ctx)
-	}
-}
-
-func LogCrit(msg string, ctx interface{}) {
-	if Log != nil {
-		Log.Crit(msg, ctx)
-	}
-}
-
-// Wrappers around Logger interface functions that send a string to the Logger
-// by running it through fmt.Sprintf().
-func LogInfof(format string, args ...interface{}) {
-	if Log != nil {
-		Log.Info(fmt.Sprintf(format, args...))
-	}
-}
-
-func LogDebugf(format string, args ...interface{}) {
-	if Log != nil {
-		Log.Debug(fmt.Sprintf(format, args...))
-	}
-}
-
-func LogWarnf(format string, args ...interface{}) {
-	if Log != nil {
-		Log.Warn(fmt.Sprintf(format, args...))
-	}
-}
-
-func LogErrorf(format string, args ...interface{}) {
-	if Log != nil {
-		Log.Error(fmt.Sprintf(format, args...))
-	}
-}
-
-func LogCritf(format string, args ...interface{}) {
-	if Log != nil {
-		Log.Crit(fmt.Sprintf(format, args...))
-	}
-}
-
-func PrintStack() {
-	buf := make([]byte, 1<<16)
-	runtime.Stack(buf, true)
-	LogErrorf("%s", buf)
-}
diff --git a/shared/log_debug.go b/shared/log_debug.go
deleted file mode 100644
index fdded57..0000000
--- a/shared/log_debug.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// +build logdebug
-
-package shared
-
-import (
-	"fmt"
-	"runtime"
-)
-
-type Logger interface {
-	Debug(msg string, ctx ...interface{})
-	Info(msg string, ctx ...interface{})
-	Warn(msg string, ctx ...interface{})
-	Error(msg string, ctx ...interface{})
-	Crit(msg string, ctx ...interface{})
-}
-
-var Log Logger
-
-type nullLogger struct{}
-
-func (nl nullLogger) Debug(msg string, ctx ...interface{}) {}
-func (nl nullLogger) Info(msg string, ctx ...interface{})  {}
-func (nl nullLogger) Warn(msg string, ctx ...interface{})  {}
-func (nl nullLogger) Error(msg string, ctx ...interface{}) {}
-func (nl nullLogger) Crit(msg string, ctx ...interface{})  {}
-
-func init() {
-	Log = nullLogger{}
-}
-
-// General wrappers around Logger interface functions.
-func LogDebug(msg string, ctx interface{}) {
-	if Log != nil {
-		pc, fn, line, _ := runtime.Caller(1)
-		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Debug(msg, ctx)
-	}
-}
-
-func LogInfo(msg string, ctx interface{}) {
-	if Log != nil {
-		pc, fn, line, _ := runtime.Caller(1)
-		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Info(msg, ctx)
-	}
-}
-
-func LogWarn(msg string, ctx interface{}) {
-	if Log != nil {
-		pc, fn, line, _ := runtime.Caller(1)
-		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Warn(msg, ctx)
-	}
-}
-
-func LogError(msg string, ctx interface{}) {
-	if Log != nil {
-		pc, fn, line, _ := runtime.Caller(1)
-		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Error(msg, ctx)
-	}
-}
-
-func LogCrit(msg string, ctx interface{}) {
-	if Log != nil {
-		pc, fn, line, _ := runtime.Caller(1)
-		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Crit(msg, ctx)
-	}
-}
-
-// Wrappers around Logger interface functions that send a string to the Logger
-// by running it through fmt.Sprintf().
-func LogInfof(format string, args ...interface{}) {
-	if Log != nil {
-		msg := fmt.Sprintf(format, args...)
-		pc, fn, line, _ := runtime.Caller(1)
-		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Info(msg)
-	}
-}
-
-func LogDebugf(format string, args ...interface{}) {
-	if Log != nil {
-		msg := fmt.Sprintf(format, args...)
-		pc, fn, line, _ := runtime.Caller(1)
-		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Debug(msg)
-	}
-}
-
-func LogWarnf(format string, args ...interface{}) {
-	if Log != nil {
-		msg := fmt.Sprintf(format, args...)
-		pc, fn, line, _ := runtime.Caller(1)
-		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Warn(msg)
-	}
-}
-
-func LogErrorf(format string, args ...interface{}) {
-	if Log != nil {
-		msg := fmt.Sprintf(format, args...)
-		pc, fn, line, _ := runtime.Caller(1)
-		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Error(msg)
-	}
-}
-
-func LogCritf(format string, args ...interface{}) {
-	if Log != nil {
-		msg := fmt.Sprintf(format, args...)
-		pc, fn, line, _ := runtime.Caller(1)
-		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Crit(msg)
-	}
-}
-
-func PrintStack() {
-	buf := make([]byte, 1<<16)
-	runtime.Stack(buf, true)
-	LogErrorf("%s", buf)
-}
diff --git a/shared/logger/log.go b/shared/logger/log.go
new file mode 100644
index 0000000..b811db0
--- /dev/null
+++ b/shared/logger/log.go
@@ -0,0 +1,99 @@
+// +build !logdebug
+
+package logger
+
+import (
+	"fmt"
+	"runtime"
+)
+
+type Logger interface {
+	Debug(msg string, ctx ...interface{})
+	Info(msg string, ctx ...interface{})
+	Warn(msg string, ctx ...interface{})
+	Error(msg string, ctx ...interface{})
+	Crit(msg string, ctx ...interface{})
+}
+
+var Log Logger
+
+type nullLogger struct{}
+
+func (nl nullLogger) Debug(msg string, ctx ...interface{}) {}
+func (nl nullLogger) Info(msg string, ctx ...interface{})  {}
+func (nl nullLogger) Warn(msg string, ctx ...interface{})  {}
+func (nl nullLogger) Error(msg string, ctx ...interface{}) {}
+func (nl nullLogger) Crit(msg string, ctx ...interface{})  {}
+
+func init() {
+	Log = nullLogger{}
+}
+
+// General wrappers around Logger interface functions.
+func Debug(msg string, ctx interface{}) {
+	if Log != nil {
+		Log.Debug(msg, ctx)
+	}
+}
+
+func Info(msg string, ctx interface{}) {
+	if Log != nil {
+		Log.Info(msg, ctx)
+	}
+}
+
+func Warn(msg string, ctx interface{}) {
+	if Log != nil {
+		Log.Warn(msg, ctx)
+	}
+}
+
+func Error(msg string, ctx interface{}) {
+	if Log != nil {
+		Log.Error(msg, ctx)
+	}
+}
+
+func Crit(msg string, ctx interface{}) {
+	if Log != nil {
+		Log.Crit(msg, ctx)
+	}
+}
+
+// Wrappers around Logger interface functions that send a string to the Logger
+// by running it through fmt.Sprintf().
+func Infof(format string, args ...interface{}) {
+	if Log != nil {
+		Log.Info(fmt.Sprintf(format, args...))
+	}
+}
+
+func Debugf(format string, args ...interface{}) {
+	if Log != nil {
+		Log.Debug(fmt.Sprintf(format, args...))
+	}
+}
+
+func Warnf(format string, args ...interface{}) {
+	if Log != nil {
+		Log.Warn(fmt.Sprintf(format, args...))
+	}
+}
+
+func Errorf(format string, args ...interface{}) {
+	if Log != nil {
+		Log.Error(fmt.Sprintf(format, args...))
+	}
+}
+
+func Critf(format string, args ...interface{}) {
+	if Log != nil {
+		Log.Crit(fmt.Sprintf(format, args...))
+	}
+}
+
+func PrintStack() {
+	buf := make([]byte, 1<<16)
+	runtime.Stack(buf, true)
+	Errorf("%s", buf)
+}
diff --git a/shared/logger/log_debug.go b/shared/logger/log_debug.go
new file mode 100644
index 0000000..0cc1ab1
--- /dev/null
+++ b/shared/logger/log_debug.go
@@ -0,0 +1,124 @@
+// +build logdebug
+
+package logger
+
+import (
+	"fmt"
+	"runtime"
+)
+
+type Logger interface {
+	Debug(msg string, ctx ...interface{})
+	Info(msg string, ctx ...interface{})
+	Warn(msg string, ctx ...interface{})
+	Error(msg string, ctx ...interface{})
+	Crit(msg string, ctx ...interface{})
+}
+
+var Log Logger
+
+type nullLogger struct{}
+
+func (nl nullLogger) Debug(msg string, ctx ...interface{}) {}
+func (nl nullLogger) Info(msg string, ctx ...interface{})  {}
+func (nl nullLogger) Warn(msg string, ctx ...interface{})  {}
+func (nl nullLogger) Error(msg string, ctx ...interface{}) {}
+func (nl nullLogger) Crit(msg string, ctx ...interface{})  {}
+
+func init() {
+	Log = nullLogger{}
+}
+
+// General wrappers around Logger interface functions.
+func Debug(msg string, ctx interface{}) {
+	if Log != nil {
+		pc, fn, line, _ := runtime.Caller(1)
+		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Debug(msg, ctx)
+	}
+}
+
+func Info(msg string, ctx interface{}) {
+	if Log != nil {
+		pc, fn, line, _ := runtime.Caller(1)
+		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Info(msg, ctx)
+	}
+}
+
+func Warn(msg string, ctx interface{}) {
+	if Log != nil {
+		pc, fn, line, _ := runtime.Caller(1)
+		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Warn(msg, ctx)
+	}
+}
+
+func Error(msg string, ctx interface{}) {
+	if Log != nil {
+		pc, fn, line, _ := runtime.Caller(1)
+		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Error(msg, ctx)
+	}
+}
+
+func Crit(msg string, ctx interface{}) {
+	if Log != nil {
+		pc, fn, line, _ := runtime.Caller(1)
+		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Crit(msg, ctx)
+	}
+}
+
+// Wrappers around Logger interface functions that send a string to the Logger
+// by running it through fmt.Sprintf().
+func Infof(format string, args ...interface{}) {
+	if Log != nil {
+		msg := fmt.Sprintf(format, args...)
+		pc, fn, line, _ := runtime.Caller(1)
+		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Info(msg)
+	}
+}
+
+func Debugf(format string, args ...interface{}) {
+	if Log != nil {
+		msg := fmt.Sprintf(format, args...)
+		pc, fn, line, _ := runtime.Caller(1)
+		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Debug(msg)
+	}
+}
+
+func Warnf(format string, args ...interface{}) {
+	if Log != nil {
+		msg := fmt.Sprintf(format, args...)
+		pc, fn, line, _ := runtime.Caller(1)
+		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Warn(msg)
+	}
+}
+
+func Errorf(format string, args ...interface{}) {
+	if Log != nil {
+		msg := fmt.Sprintf(format, args...)
+		pc, fn, line, _ := runtime.Caller(1)
+		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Error(msg)
+	}
+}
+
+func Critf(format string, args ...interface{}) {
+	if Log != nil {
+		msg := fmt.Sprintf(format, args...)
+		pc, fn, line, _ := runtime.Caller(1)
+		msg = fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
+		Log.Crit(msg)
+	}
+}
+
+func PrintStack() {
+	buf := make([]byte, 1<<16)
+	runtime.Stack(buf, true)
+	Errorf("%s", buf)
+}
diff --git a/shared/logging/log.go b/shared/logging/log.go
index f073028..15b8ac9 100644
--- a/shared/logging/log.go
+++ b/shared/logging/log.go
@@ -5,14 +5,14 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/lxc/lxd/shared"
+	log "gopkg.in/inconshreveable/log15.v2"
 	"gopkg.in/inconshreveable/log15.v2/term"
 
-	log "gopkg.in/inconshreveable/log15.v2"
+	"github.com/lxc/lxd/shared/logger"
 )
 
-// GetLogger returns a logger suitable for using as shared.Log.
-func GetLogger(syslog string, logfile string, verbose bool, debug bool, customHandler log.Handler) (shared.Logger, error) {
+// GetLogger returns a logger suitable for using as logger.Log.
+func GetLogger(syslog string, logfile string, verbose bool, debug bool, customHandler log.Handler) (logger.Logger, error) {
 	Log := log.New()
 
 	var handlers []log.Handler
@@ -81,7 +81,7 @@ func GetLogger(syslog string, logfile string, verbose bool, debug bool, customHa
 	return Log, nil
 }
 
-func AddContext(logger shared.Logger, ctx log.Ctx) shared.Logger {
+func AddContext(logger logger.Logger, ctx log.Ctx) logger.Logger {
 	log15logger, ok := logger.(log.Logger)
 	if !ok {
 		logger.Error("couldn't downcast logger to add context", log.Ctx{"logger": log15logger, "ctx": ctx})
diff --git a/shared/network.go b/shared/network.go
index c60ba74..e9857e5 100644
--- a/shared/network.go
+++ b/shared/network.go
@@ -12,6 +12,8 @@ import (
 	"time"
 
 	"github.com/gorilla/websocket"
+
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func RFC3493Dialer(network, address string) (net.Conn, error) {
@@ -163,14 +165,14 @@ func WebsocketSendStream(conn *websocket.Conn, r io.Reader, bufferSize int) chan
 
 			w, err := conn.NextWriter(websocket.BinaryMessage)
 			if err != nil {
-				LogDebugf("Got error getting next writer %s", err)
+				logger.Debugf("Got error getting next writer %s", err)
 				break
 			}
 
 			_, err = w.Write(buf)
 			w.Close()
 			if err != nil {
-				LogDebugf("Got err writing %s", err)
+				logger.Debugf("Got err writing %s", err)
 				break
 			}
 		}
@@ -188,23 +190,23 @@ func WebsocketRecvStream(w io.Writer, conn *websocket.Conn) chan bool {
 		for {
 			mt, r, err := conn.NextReader()
 			if mt == websocket.CloseMessage {
-				LogDebugf("Got close message for reader")
+				logger.Debugf("Got close message for reader")
 				break
 			}
 
 			if mt == websocket.TextMessage {
-				LogDebugf("got message barrier")
+				logger.Debugf("got message barrier")
 				break
 			}
 
 			if err != nil {
-				LogDebugf("Got error getting next reader %s, %s", err, w)
+				logger.Debugf("Got error getting next reader %s, %s", err, w)
 				break
 			}
 
 			buf, err := ioutil.ReadAll(r)
 			if err != nil {
-				LogDebugf("Got error writing to writer %s", err)
+				logger.Debugf("Got error writing to writer %s", err)
 				break
 			}
 
@@ -214,11 +216,11 @@ func WebsocketRecvStream(w io.Writer, conn *websocket.Conn) chan bool {
 
 			i, err := w.Write(buf)
 			if i != len(buf) {
-				LogDebugf("Didn't write all of buf")
+				logger.Debugf("Didn't write all of buf")
 				break
 			}
 			if err != nil {
-				LogDebugf("Error writing buf %s", err)
+				logger.Debugf("Error writing buf %s", err)
 				break
 			}
 		}
@@ -238,21 +240,21 @@ func defaultReader(conn *websocket.Conn, r io.ReadCloser, readDone chan<- bool)
 		buf, ok := <-in
 		if !ok {
 			r.Close()
-			LogDebugf("sending write barrier")
+			logger.Debugf("sending write barrier")
 			conn.WriteMessage(websocket.TextMessage, []byte{})
 			readDone <- true
 			return
 		}
 		w, err := conn.NextWriter(websocket.BinaryMessage)
 		if err != nil {
-			LogDebugf("Got error getting next writer %s", err)
+			logger.Debugf("Got error getting next writer %s", err)
 			break
 		}
 
 		_, err = w.Write(buf)
 		w.Close()
 		if err != nil {
-			LogDebugf("Got err writing %s", err)
+			logger.Debugf("Got err writing %s", err)
 			break
 		}
 	}
@@ -266,32 +268,32 @@ func defaultWriter(conn *websocket.Conn, w io.WriteCloser, writeDone chan<- bool
 	for {
 		mt, r, err := conn.NextReader()
 		if err != nil {
-			LogDebugf("Got error getting next reader %s, %s", err, w)
+			logger.Debugf("Got error getting next reader %s, %s", err, w)
 			break
 		}
 
 		if mt == websocket.CloseMessage {
-			LogDebugf("Got close message for reader")
+			logger.Debugf("Got close message for reader")
 			break
 		}
 
 		if mt == websocket.TextMessage {
-			LogDebugf("Got message barrier, resetting stream")
+			logger.Debugf("Got message barrier, resetting stream")
 			break
 		}
 
 		buf, err := ioutil.ReadAll(r)
 		if err != nil {
-			LogDebugf("Got error writing to writer %s", err)
+			logger.Debugf("Got error writing to writer %s", err)
 			break
 		}
 		i, err := w.Write(buf)
 		if i != len(buf) {
-			LogDebugf("Didn't write all of buf")
+			logger.Debugf("Didn't write all of buf")
 			break
 		}
 		if err != nil {
-			LogDebugf("Error writing buf %s", err)
+			logger.Debugf("Error writing buf %s", err)
 			break
 		}
 	}
diff --git a/shared/network_linux.go b/shared/network_linux.go
index 3bee792..09ecd98 100644
--- a/shared/network_linux.go
+++ b/shared/network_linux.go
@@ -6,6 +6,8 @@ import (
 	"io"
 
 	"github.com/gorilla/websocket"
+
+	"github.com/lxc/lxd/shared/logger"
 )
 
 func WebsocketExecMirror(conn *websocket.Conn, w io.WriteCloser, r io.ReadCloser, exited chan bool, fd int) (chan bool, chan bool) {
@@ -20,21 +22,21 @@ func WebsocketExecMirror(conn *websocket.Conn, w io.WriteCloser, r io.ReadCloser
 			buf, ok := <-in
 			if !ok {
 				r.Close()
-				LogDebugf("sending write barrier")
+				logger.Debugf("sending write barrier")
 				conn.WriteMessage(websocket.TextMessage, []byte{})
 				readDone <- true
 				return
 			}
 			w, err := conn.NextWriter(websocket.BinaryMessage)
 			if err != nil {
-				LogDebugf("Got error getting next writer %s", err)
+				logger.Debugf("Got error getting next writer %s", err)
 				break
 			}
 
 			_, err = w.Write(buf)
 			w.Close()
 			if err != nil {
-				LogDebugf("Got err writing %s", err)
+				logger.Debugf("Got err writing %s", err)
 				break
 			}
 		}
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 68310cb..a01dbc1 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -15,6 +15,8 @@ import (
 	"sync/atomic"
 	"syscall"
 	"unsafe"
+
+	"github.com/lxc/lxd/shared/logger"
 )
 
 // #cgo LDFLAGS: -lutil -lpthread
@@ -565,13 +567,13 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 
 		ret, revents, err := GetPollRevents(fd, 0, (POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP))
 		if ret < 0 {
-			LogErrorf("Failed to poll(POLLIN | POLLPRI | POLLHUP | POLLRDHUP) on file descriptor: %s.", err)
+			logger.Errorf("Failed to poll(POLLIN | POLLPRI | POLLHUP | POLLRDHUP) on file descriptor: %s.", err)
 		} else if ret > 0 {
 			if (revents & POLLERR) > 0 {
-				LogWarnf("Detected poll(POLLERR) event.")
+				logger.Warnf("Detected poll(POLLERR) event.")
 			}
 		} else if ret == 0 {
-			LogDebugf("No data in stdout: exiting.")
+			logger.Debugf("No data in stdout: exiting.")
 			once.Do(closeChannel)
 			return
 		}
@@ -592,7 +594,7 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 			if ret < 0 {
 				// This condition is only reached in cases where we are massively f*cked since we even handle
 				// EINTR in the underlying C wrapper around poll(). So let's exit here.
-				LogErrorf("Failed to poll(POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP) on file descriptor: %s. Exiting.", err)
+				logger.Errorf("Failed to poll(POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP) on file descriptor: %s. Exiting.", err)
 				return
 			}
 
@@ -601,13 +603,13 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 			// keep on reading from the pty file descriptor until we get a simple POLLHUP back.
 			both := ((revents & (POLLIN | POLLPRI)) > 0) && ((revents & (POLLHUP | POLLRDHUP)) > 0)
 			if both {
-				LogDebugf("Detected poll(POLLIN | POLLPRI | POLLHUP | POLLRDHUP) event.")
+				logger.Debugf("Detected poll(POLLIN | POLLPRI | POLLHUP | POLLRDHUP) event.")
 				read := buf[offset : offset+readSize]
 				nr, err = r.Read(read)
 			}
 
 			if (revents & POLLERR) > 0 {
-				LogWarnf("Detected poll(POLLERR) event: exiting.")
+				logger.Warnf("Detected poll(POLLERR) event: exiting.")
 				return
 			}
 
@@ -666,10 +668,10 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 					//   stdout is written out.
 					ret, revents, err := GetPollRevents(fd, 0, (POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP))
 					if ret < 0 {
-						LogErrorf("Failed to poll(POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP) on file descriptor: %s. Exiting.", err)
+						logger.Errorf("Failed to poll(POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP) on file descriptor: %s. Exiting.", err)
 						return
 					} else if (revents & (POLLHUP | POLLRDHUP)) == 0 {
-						LogDebugf("Exiting but background processes are still running.")
+						logger.Debugf("Exiting but background processes are still running.")
 						return
 					}
 				}
@@ -680,7 +682,7 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 			// The attached process has exited and we have read all data that may have
 			// been buffered.
 			if ((revents & (POLLHUP | POLLRDHUP)) > 0) && !both {
-				LogDebugf("Detected poll(POLLHUP) event: exiting.")
+				logger.Debugf("Detected poll(POLLHUP) event: exiting.")
 				return
 			}
 

From 220d6385c59c7df0db85fe9a119da6c012db638f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 21:55:48 -0400
Subject: [PATCH 02/10] shared/logger: Add pretty formatting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/logger/format.go    | 15 +++++++++++++++
 shared/logger/log.go       | 20 ++++++++++----------
 shared/logger/log_debug.go | 20 ++++++++++----------
 3 files changed, 35 insertions(+), 20 deletions(-)
 create mode 100644 shared/logger/format.go

diff --git a/shared/logger/format.go b/shared/logger/format.go
new file mode 100644
index 0000000..16f2e83
--- /dev/null
+++ b/shared/logger/format.go
@@ -0,0 +1,15 @@
+package logger
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+func Pretty(input interface{}) string {
+	pretty, err := json.MarshalIndent(input, "\t", "\t")
+	if err != nil {
+		return fmt.Sprintf("%s", input)
+	}
+
+	return fmt.Sprintf("\n\t%s", pretty)
+}
diff --git a/shared/logger/log.go b/shared/logger/log.go
index b811db0..60148d4 100644
--- a/shared/logger/log.go
+++ b/shared/logger/log.go
@@ -30,33 +30,33 @@ func init() {
 }
 
 // General wrappers around Logger interface functions.
-func Debug(msg string, ctx interface{}) {
+func Debug(msg string, ctx ...interface{}) {
 	if Log != nil {
-		Log.Debug(msg, ctx)
+		Log.Debug(msg, ctx...)
 	}
 }
 
-func Info(msg string, ctx interface{}) {
+func Info(msg string, ctx ...interface{}) {
 	if Log != nil {
-		Log.Info(msg, ctx)
+		Log.Info(msg, ctx...)
 	}
 }
 
-func Warn(msg string, ctx interface{}) {
+func Warn(msg string, ctx ...interface{}) {
 	if Log != nil {
-		Log.Warn(msg, ctx)
+		Log.Warn(msg, ctx...)
 	}
 }
 
-func Error(msg string, ctx interface{}) {
+func Error(msg string, ctx ...interface{}) {
 	if Log != nil {
-		Log.Error(msg, ctx)
+		Log.Error(msg, ctx...)
 	}
 }
 
-func Crit(msg string, ctx interface{}) {
+func Crit(msg string, ctx ...interface{}) {
 	if Log != nil {
-		Log.Crit(msg, ctx)
+		Log.Crit(msg, ctx...)
 	}
 }
 
diff --git a/shared/logger/log_debug.go b/shared/logger/log_debug.go
index 0cc1ab1..4918553 100644
--- a/shared/logger/log_debug.go
+++ b/shared/logger/log_debug.go
@@ -30,43 +30,43 @@ func init() {
 }
 
 // General wrappers around Logger interface functions.
-func Debug(msg string, ctx interface{}) {
+func Debug(msg string, ctx ...interface{}) {
 	if Log != nil {
 		pc, fn, line, _ := runtime.Caller(1)
 		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Debug(msg, ctx)
+		Log.Debug(msg, ctx...)
 	}
 }
 
-func Info(msg string, ctx interface{}) {
+func Info(msg string, ctx ...interface{}) {
 	if Log != nil {
 		pc, fn, line, _ := runtime.Caller(1)
 		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Info(msg, ctx)
+		Log.Info(msg, ctx...)
 	}
 }
 
-func Warn(msg string, ctx interface{}) {
+func Warn(msg string, ctx ...interface{}) {
 	if Log != nil {
 		pc, fn, line, _ := runtime.Caller(1)
 		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Warn(msg, ctx)
+		Log.Warn(msg, ctx...)
 	}
 }
 
-func Error(msg string, ctx interface{}) {
+func Error(msg string, ctx ...interface{}) {
 	if Log != nil {
 		pc, fn, line, _ := runtime.Caller(1)
 		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Error(msg, ctx)
+		Log.Error(msg, ctx...)
 	}
 }
 
-func Crit(msg string, ctx interface{}) {
+func Crit(msg string, ctx ...interface{}) {
 	if Log != nil {
 		pc, fn, line, _ := runtime.Caller(1)
 		msg := fmt.Sprintf("%s: %d: %s: %s", fn, line, runtime.FuncForPC(pc).Name(), msg)
-		Log.Crit(msg, ctx)
+		Log.Crit(msg, ctx...)
 	}
 }
 

From faf740e7e978fce0a8455995ffecc435316c75b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 22:00:21 -0400
Subject: [PATCH 03/10] shared/i18n: Simplify and make golint clean
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/i18n/i18n.go            | 5 +----
 shared/i18n/i18n_linux.go      | 9 ++-------
 test/suites/static_analysis.sh | 1 +
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/shared/i18n/i18n.go b/shared/i18n/i18n.go
index 54efaa2..9a43f14 100644
--- a/shared/i18n/i18n.go
+++ b/shared/i18n/i18n.go
@@ -2,10 +2,7 @@
 
 package i18n
 
+// G returns the translated string
 func G(msgid string) string {
 	return msgid
 }
-
-func NG(msgid string, msgidPlural string, n uint64) string {
-	return msgid
-}
diff --git a/shared/i18n/i18n_linux.go b/shared/i18n/i18n_linux.go
index 80fc0b5..11399da 100644
--- a/shared/i18n/i18n_linux.go
+++ b/shared/i18n/i18n_linux.go
@@ -6,14 +6,9 @@ import (
 	"github.com/gosexy/gettext"
 )
 
-var TEXTDOMAIN = "lxd"
-
+// G returns the translated string
 func G(msgid string) string {
-	return gettext.DGettext(TEXTDOMAIN, msgid)
-}
-
-func NG(msgid string, msgidPlural string, n uint64) string {
-	return gettext.DNGettext(TEXTDOMAIN, msgid, msgidPlural, n)
+	return gettext.DGettext("lxd", msgid)
 }
 
 func init() {
diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh
index fb49c22..d6967e4 100644
--- a/test/suites/static_analysis.sh
+++ b/test/suites/static_analysis.sh
@@ -39,6 +39,7 @@ test_static_analysis() {
       golint -set_exit_status client/
       golint -set_exit_status lxc/config/
       golint -set_exit_status shared/api/
+      golint -set_exit_status shared/i18n/
     fi
 
     ## deadcode

From e209e0c835afe55c29ab4080cd74badeb31c572a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 22:04:17 -0400
Subject: [PATCH 04/10] shared/gnuflag: Fix golint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/gnuflag/flag.go         | 47 +++++++++++++++++++++++-------------------
 test/suites/static_analysis.sh |  1 +
 2 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/shared/gnuflag/flag.go b/shared/gnuflag/flag.go
index 76e04b6..94b7b84 100644
--- a/shared/gnuflag/flag.go
+++ b/shared/gnuflag/flag.go
@@ -3,27 +3,27 @@
 // license that can be found in the LICENSE file.
 
 /*
-	Package flag implements command-line flag parsing in the GNU style.
-	It is almost exactly the same as the standard flag package,
-	the only difference being the extra argument to Parse.
-
-	Command line flag syntax:
-		-f		// single letter flag
-		-fg		// two single letter flags together
-		--flag	// multiple letter flag
-		--flag x  // non-boolean flags only
-		-f x		// non-boolean flags only
-		-fx		// if f is a non-boolean flag, x is its argument.
-
-	The last three forms are not permitted for boolean flags because the
-	meaning of the command
-		cmd -f *
-	will change if there is a file called 0, false, etc.  There is currently
-	no way to turn off a boolean flag.
-
-	Flag parsing stops after the terminator "--", or just before the first
-	non-flag argument ("-" is a non-flag argument) if the interspersed
-	argument to Parse is false.
+Package gnuflag implements command-line flag parsing in the GNU style.
+It is almost exactly the same as the standard flag package,
+the only difference being the extra argument to Parse.
+
+Command line flag syntax:
+	-f		// single letter flag
+	-fg		// two single letter flags together
+	--flag	// multiple letter flag
+	--flag x  // non-boolean flags only
+	-f x		// non-boolean flags only
+	-fx		// if f is a non-boolean flag, x is its argument.
+
+The last three forms are not permitted for boolean flags because the
+meaning of the command
+	cmd -f *
+will change if there is a file called 0, false, etc.  There is currently
+no way to turn off a boolean flag.
+
+Flag parsing stops after the terminator "--", or just before the first
+non-flag argument ("-" is a non-flag argument) if the interspersed
+argument to Parse is false.
 */
 package gnuflag
 
@@ -181,8 +181,13 @@ type Value interface {
 type ErrorHandling int
 
 const (
+	// ContinueOnError will cause gnuflag to just return the error
 	ContinueOnError ErrorHandling = iota
+
+	// ExitOnError will cause gnuflag to exit with return code 2
 	ExitOnError
+
+	// PanicOnError will cause gnuflag to to call panic()
 	PanicOnError
 )
 
diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh
index d6967e4..6620055 100644
--- a/test/suites/static_analysis.sh
+++ b/test/suites/static_analysis.sh
@@ -39,6 +39,7 @@ test_static_analysis() {
       golint -set_exit_status client/
       golint -set_exit_status lxc/config/
       golint -set_exit_status shared/api/
+      golint -set_exit_status shared/gnuflag/
       golint -set_exit_status shared/i18n/
     fi
 

From af512dc3cecd3ab6f9806ffb97aab2bb39f3a020 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 22:18:25 -0400
Subject: [PATCH 05/10] shared/ioprogress: Simplify and make golint clean
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/ioprogress/reader.go    | 4 +++-
 shared/ioprogress/tracker.go   | 3 ++-
 shared/ioprogress/writer.go    | 4 +++-
 test/suites/static_analysis.sh | 1 +
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/shared/ioprogress/reader.go b/shared/ioprogress/reader.go
index 262aa40..299cb6b 100644
--- a/shared/ioprogress/reader.go
+++ b/shared/ioprogress/reader.go
@@ -4,11 +4,13 @@ import (
 	"io"
 )
 
+// ProgressReader is a wrapper around ReadCloser which allows for progress tracking
 type ProgressReader struct {
 	io.ReadCloser
 	Tracker *ProgressTracker
 }
 
+// Read in ProgressReader is the same as io.Read
 func (pt *ProgressReader) Read(p []byte) (int, error) {
 	// Do normal reader tasks
 	n, err := pt.ReadCloser.Read(p)
@@ -16,7 +18,7 @@ func (pt *ProgressReader) Read(p []byte) (int, error) {
 	// Do the actual progress tracking
 	if pt.Tracker != nil {
 		pt.Tracker.total += int64(n)
-		pt.Tracker.Update(n)
+		pt.Tracker.update(n)
 	}
 
 	return n, err
diff --git a/shared/ioprogress/tracker.go b/shared/ioprogress/tracker.go
index 78c730b..ad79089 100644
--- a/shared/ioprogress/tracker.go
+++ b/shared/ioprogress/tracker.go
@@ -4,6 +4,7 @@ import (
 	"time"
 )
 
+// ProgressTracker provides the stream information needed for tracking
 type ProgressTracker struct {
 	Length  int64
 	Handler func(int64, int64)
@@ -14,7 +15,7 @@ type ProgressTracker struct {
 	last       *time.Time
 }
 
-func (pt *ProgressTracker) Update(n int) {
+func (pt *ProgressTracker) update(n int) {
 	// Skip the rest if no handler attached
 	if pt.Handler == nil {
 		return
diff --git a/shared/ioprogress/writer.go b/shared/ioprogress/writer.go
index 708911b..f45b45e 100644
--- a/shared/ioprogress/writer.go
+++ b/shared/ioprogress/writer.go
@@ -4,11 +4,13 @@ import (
 	"io"
 )
 
+// ProgressWriter is a wrapper around WriteCloser which allows for progress tracking
 type ProgressWriter struct {
 	io.WriteCloser
 	Tracker *ProgressTracker
 }
 
+// Write in ProgressWriter is the same as io.Write
 func (pt *ProgressWriter) Write(p []byte) (int, error) {
 	// Do normal writer tasks
 	n, err := pt.WriteCloser.Write(p)
@@ -16,7 +18,7 @@ func (pt *ProgressWriter) Write(p []byte) (int, error) {
 	// Do the actual progress tracking
 	if pt.Tracker != nil {
 		pt.Tracker.total += int64(n)
-		pt.Tracker.Update(n)
+		pt.Tracker.update(n)
 	}
 
 	return n, err
diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh
index 6620055..5c49266 100644
--- a/test/suites/static_analysis.sh
+++ b/test/suites/static_analysis.sh
@@ -41,6 +41,7 @@ test_static_analysis() {
       golint -set_exit_status shared/api/
       golint -set_exit_status shared/gnuflag/
       golint -set_exit_status shared/i18n/
+      golint -set_exit_status shared/ioprogress/
     fi
 
     ## deadcode

From 369912618db38122823157ddae04a24b46dbca9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 22:29:06 -0400
Subject: [PATCH 06/10] shared/version: Make golint clean
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/version/flex.go         | 12 ++++--------
 test/suites/static_analysis.sh |  1 +
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/shared/version/flex.go b/shared/version/flex.go
index 0c87f33..e4075de 100644
--- a/shared/version/flex.go
+++ b/shared/version/flex.go
@@ -1,14 +1,10 @@
-/* This is a FLEXible file which can be used by both client and daemon.
- * Teehee.
- */
 package version
 
+// Version contains the LXD version number
 var Version = "2.12"
+
+// UserAgent contains a string suitable as a user-agent
 var UserAgent = "LXD " + Version
 
-/*
- * Please increment the api compat number every time you change the API.
- *
- * Version 1.0: ping
- */
+// APIVersion contains the API base version. Only bumped for backward incompatible changes.
 var APIVersion = "1.0"
diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh
index 5c49266..aa69b92 100644
--- a/test/suites/static_analysis.sh
+++ b/test/suites/static_analysis.sh
@@ -42,6 +42,7 @@ test_static_analysis() {
       golint -set_exit_status shared/gnuflag/
       golint -set_exit_status shared/i18n/
       golint -set_exit_status shared/ioprogress/
+      golint -set_exit_status shared/version/
     fi
 
     ## deadcode

From 288db3049d21ee9a9b12f1c54c7eb3544d24a251 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 5 Apr 2017 22:09:18 -0400
Subject: [PATCH 07/10] lxc/config: Fix path handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxc/config/remote.go | 57 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 15 deletions(-)

diff --git a/lxc/config/remote.go b/lxc/config/remote.go
index dddea37..3317ccc 100644
--- a/lxc/config/remote.go
+++ b/lxc/config/remote.go
@@ -2,6 +2,7 @@ package config
 
 import (
 	"fmt"
+	"io/ioutil"
 	"strings"
 
 	"github.com/lxc/lxd/client"
@@ -45,11 +46,14 @@ func (c *Config) GetContainerServer(name string) (lxd.ContainerServer, error) {
 	}
 
 	// Get connection arguments
-	args := c.getConnectionArgs(name)
+	args, err := c.getConnectionArgs(name)
+	if err != nil {
+		return nil, err
+	}
 
 	// Unix socket
 	if strings.HasPrefix(remote.Addr, "unix:") {
-		d, err := lxd.ConnectLXDUnix(strings.TrimPrefix(strings.TrimPrefix(remote.Addr, "unix:"), "//"), &args)
+		d, err := lxd.ConnectLXDUnix(strings.TrimPrefix(strings.TrimPrefix(remote.Addr, "unix:"), "//"), args)
 		if err != nil {
 			return nil, err
 		}
@@ -62,7 +66,7 @@ func (c *Config) GetContainerServer(name string) (lxd.ContainerServer, error) {
 		return nil, fmt.Errorf("Missing TLS client certificate and key")
 	}
 
-	d, err := lxd.ConnectLXD(remote.Addr, &args)
+	d, err := lxd.ConnectLXD(remote.Addr, args)
 	if err != nil {
 		return nil, err
 	}
@@ -79,11 +83,14 @@ func (c *Config) GetImageServer(name string) (lxd.ImageServer, error) {
 	}
 
 	// Get connection arguments
-	args := c.getConnectionArgs(name)
+	args, err := c.getConnectionArgs(name)
+	if err != nil {
+		return nil, err
+	}
 
 	// Unix socket
 	if strings.HasPrefix(remote.Addr, "unix:") {
-		d, err := lxd.ConnectLXDUnix(strings.TrimPrefix(strings.TrimPrefix(remote.Addr, "unix:"), "//"), &args)
+		d, err := lxd.ConnectLXDUnix(strings.TrimPrefix(strings.TrimPrefix(remote.Addr, "unix:"), "//"), args)
 		if err != nil {
 			return nil, err
 		}
@@ -93,7 +100,7 @@ func (c *Config) GetImageServer(name string) (lxd.ImageServer, error) {
 
 	// HTTPs (simplestreams)
 	if remote.Protocol == "simplestreams" {
-		d, err := lxd.ConnectSimpleStreams(remote.Addr, &args)
+		d, err := lxd.ConnectSimpleStreams(remote.Addr, args)
 		if err != nil {
 			return nil, err
 		}
@@ -102,7 +109,7 @@ func (c *Config) GetImageServer(name string) (lxd.ImageServer, error) {
 	}
 
 	// HTTPs (LXD)
-	d, err := lxd.ConnectPublicLXD(remote.Addr, &args)
+	d, err := lxd.ConnectPublicLXD(remote.Addr, args)
 	if err != nil {
 		return nil, err
 	}
@@ -110,30 +117,50 @@ func (c *Config) GetImageServer(name string) (lxd.ImageServer, error) {
 	return d, nil
 }
 
-func (c *Config) getConnectionArgs(name string) lxd.ConnectionArgs {
+func (c *Config) getConnectionArgs(name string) (*lxd.ConnectionArgs, error) {
 	args := lxd.ConnectionArgs{
 		UserAgent: c.UserAgent,
 	}
 
 	// Client certificate
-	if !shared.PathExists(c.ConfigPath("client.crt")) {
-		args.TLSClientCert = c.ConfigPath("client.crt")
+	if shared.PathExists(c.ConfigPath("client.crt")) {
+		content, err := ioutil.ReadFile(c.ConfigPath("client.crt"))
+		if err != nil {
+			return nil, err
+		}
+
+		args.TLSClientCert = string(content)
 	}
 
 	// Client key
-	if !shared.PathExists(c.ConfigPath("client.key")) {
-		args.TLSClientKey = c.ConfigPath("client.key")
+	if shared.PathExists(c.ConfigPath("client.key")) {
+		content, err := ioutil.ReadFile(c.ConfigPath("client.key"))
+		if err != nil {
+			return nil, err
+		}
+
+		args.TLSClientKey = string(content)
 	}
 
 	// Client CA
 	if shared.PathExists(c.ConfigPath("client.ca")) {
-		args.TLSCA = c.ConfigPath("client.ca")
+		content, err := ioutil.ReadFile(c.ConfigPath("client.ca"))
+		if err != nil {
+			return nil, err
+		}
+
+		args.TLSCA = string(content)
 	}
 
 	// Server certificate
 	if shared.PathExists(c.ServerCertPath(name)) {
-		args.TLSServerCert = c.ServerCertPath(name)
+		content, err := ioutil.ReadFile(c.ServerCertPath(name))
+		if err != nil {
+			return nil, err
+		}
+
+		args.TLSServerCert = string(content)
 	}
 
-	return args
+	return &args, nil
 }

From 98679dba528ce20d415a431291805beef83e124f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 6 Apr 2017 21:56:09 -0400
Subject: [PATCH 08/10] client: Add basic logging code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 client/connection.go |  9 +++++++++
 client/lxd.go        | 24 ++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/client/connection.go b/client/connection.go
index 0af923f..725b13c 100644
--- a/client/connection.go
+++ b/client/connection.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"path/filepath"
 
+	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/simplestreams"
 )
 
@@ -38,6 +39,8 @@ type ConnectionArgs struct {
 //
 // Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
 func ConnectLXD(url string, args *ConnectionArgs) (ContainerServer, error) {
+	logger.Infof("Connecting to a remote LXD over HTTPs")
+
 	// Use empty args if not specified
 	if args == nil {
 		args = &ConnectionArgs{}
@@ -71,6 +74,8 @@ func ConnectLXD(url string, args *ConnectionArgs) (ContainerServer, error) {
 // If the path argument is empty, then $LXD_DIR/unix.socket will be used.
 // If that one isn't set either, then the path will default to /var/lib/lxd/unix.socket.
 func ConnectLXDUnix(path string, args *ConnectionArgs) (ContainerServer, error) {
+	logger.Infof("Connecting to a local LXD over a Unix socket")
+
 	// Use empty args if not specified
 	if args == nil {
 		args = &ConnectionArgs{}
@@ -115,6 +120,8 @@ func ConnectLXDUnix(path string, args *ConnectionArgs) (ContainerServer, error)
 //
 // Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
 func ConnectPublicLXD(url string, args *ConnectionArgs) (ImageServer, error) {
+	logger.Infof("Connecting to a remote public LXD over HTTPs")
+
 	// Use empty args if not specified
 	if args == nil {
 		args = &ConnectionArgs{}
@@ -147,6 +154,8 @@ func ConnectPublicLXD(url string, args *ConnectionArgs) (ImageServer, error) {
 //
 // Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
 func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error) {
+	logger.Infof("Connecting to a remote simplestreams server")
+
 	// Use empty args if not specified
 	if args == nil {
 		args = &ConnectionArgs{}
diff --git a/client/lxd.go b/client/lxd.go
index 2d7707f..8b2f01a 100644
--- a/client/lxd.go
+++ b/client/lxd.go
@@ -11,6 +11,7 @@ import (
 	"github.com/gorilla/websocket"
 
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/logger"
 )
 
 // ProtocolLXD represents a LXD API server
@@ -51,6 +52,13 @@ func (r *ProtocolLXD) rawQuery(method string, url string, data interface{}, ETag
 	var req *http.Request
 	var err error
 
+	// Log the request
+	logger.Info("Sending request to LXD",
+		"method", method,
+		"url", url,
+		"etag", ETag,
+	)
+
 	// Get a new HTTP request setup
 	if data != nil {
 		// Encode the provided data
@@ -68,6 +76,11 @@ func (r *ProtocolLXD) rawQuery(method string, url string, data interface{}, ETag
 
 		// Set the encoding accordingly
 		req.Header.Set("Content-Type", "application/json")
+
+		// Log the data
+		if data != nil {
+			logger.Debugf(logger.Pretty(data))
+		}
 	} else {
 		// No data to be sent along with the request
 		req, err = http.NewRequest(method, url, nil)
@@ -136,6 +149,10 @@ func (r *ProtocolLXD) queryStruct(method string, path string, data interface{},
 		return "", err
 	}
 
+	// Log the data
+	logger.Debugf("Got response struct from LXD")
+	logger.Debugf(logger.Pretty(target))
+
 	return etag, nil
 }
 
@@ -159,6 +176,10 @@ func (r *ProtocolLXD) queryOperation(method string, path string, data interface{
 		chActive:  make(chan bool),
 	}
 
+	// Log the data
+	logger.Debugf("Got operation from LXD")
+	logger.Debugf(logger.Pretty(op.Operation))
+
 	return &op, etag, nil
 }
 
@@ -185,6 +206,9 @@ func (r *ProtocolLXD) rawWebsocket(url string) (*websocket.Conn, error) {
 		return nil, err
 	}
 
+	// Log the data
+	logger.Debugf("Connected to the websocket")
+
 	return conn, err
 }
 

From f0954b405bec15dc8ea2c883e23a932a4ee84141 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 9 Apr 2017 22:55:30 -0400
Subject: [PATCH 09/10] db: Deal with the case where no updates exist
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This can't ever happen for LXD because we're past this point now but
still worth fixing for people copy/pasting from our code :)

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/db.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lxd/db.go b/lxd/db.go
index 291fa60..923c293 100644
--- a/lxd/db.go
+++ b/lxd/db.go
@@ -265,6 +265,10 @@ func dbGetSchema(db *sql.DB) (v int) {
 }
 
 func dbGetLatestSchema() int {
+	if len(dbUpdates) == 0 {
+		return 0
+	}
+
 	return dbUpdates[len(dbUpdates)-1].version
 }
 

From e60d0c595608bd0cedacad6e7d3eae3775c66c69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 10 Apr 2017 01:55:05 -0400
Subject: [PATCH 10/10] doc: Drop mention of PKI CRL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

As this never actually got implemented.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/lxd-ssl-authentication.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/lxd-ssl-authentication.md b/doc/lxd-ssl-authentication.md
index efd8cf4..70ed7bc 100644
--- a/doc/lxd-ssl-authentication.md
+++ b/doc/lxd-ssl-authentication.md
@@ -52,7 +52,6 @@ Those certificates and keys are manually put in place on the various
 machines, replacing the automatically generated ones.
 
 The CA certificate is also added to all machines.
-A CRL may also accompany the CA certificate.
 
 In that mode, any connection to a LXD daemon will be done using the
 preseeded CA certificate. If the server certificate isn't signed by the


More information about the lxc-devel mailing list