[lxc-devel] [lxd/master] build: add debug logging

brauner on Github lxc-bot at linuxcontainers.org
Fri Mar 24 00:55:01 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 8408 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170324/56e90791/attachment.bin>
-------------- next part --------------
From 746354e6a42965ce5dcd97830cef8053d8fbd924 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 24 Mar 2017 01:46:59 +0100
Subject: [PATCH] build: add debug logging

This allows to build LXD with debug logging enabled which prints the file name,
line number, and function name in all log output. This is mostly meant for
development purposes.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 Makefile            |   6 +++
 shared/log.go       |   2 +
 shared/log_debug.go | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 shared/log_debug.go

diff --git a/Makefile b/Makefile
index 25d894e..05e5f0b 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,12 @@ update:
 	go get -t -v -d -u ./...
 	@echo "Dependencies updated"
 
+.PHONY: debug
+debug:
+	go get -t -v -d ./...
+	go install -v $(TAGS) -tags logdebug $(DEBUG) ./...
+	@echo "LXD built successfully"
+
 # This only needs to be done when migrate.proto is actually changed; since we
 # commit the .pb.go in the tree and it's not expected to change very often,
 # it's not a default build step.
diff --git a/shared/log.go b/shared/log.go
index f696feb..ec464e0 100644
--- a/shared/log.go
+++ b/shared/log.go
@@ -1,3 +1,5 @@
+// +build !logdebug
+
 package shared
 
 import (
diff --git a/shared/log_debug.go b/shared/log_debug.go
new file mode 100644
index 0000000..fdded57
--- /dev/null
+++ b/shared/log_debug.go
@@ -0,0 +1,124 @@
+// +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)
+}


More information about the lxc-devel mailing list