diff --git a/build/ci/.documentation-ci.yml b/build/ci/.documentation-ci.yml
index 76e5303f163a2a7f5e0206dba6bfe2d938218433..1ca7e7dc29d1fcd12cf266fcb88b1f2919f03211 100644
--- a/build/ci/.documentation-ci.yml
+++ b/build/ci/.documentation-ci.yml
@@ -18,23 +18,20 @@ documentation:pdf:
     - documentation/design/documentation.pdf
 
 .mdbook_common: &rust
-  before_script:
-      - cargo install mdbook
-  image:
-    name: rust:latest
+  image: 
+    name: $CI_REGISTRY/danet/internetworking/mdbook:latest
+    entrypoint:
+      - ''
   stage: deploy
   script:
   - mdbook build documentation --dest-dir public
-  cache:
-    paths:
-    - /root/.cargo/
 
 documentation:static:
   rules:
     - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
   artifacts:
     paths:
-      - documentation/public
+      - public
     expire_in: 1 week
   <<: *rust
 
diff --git a/cmd/gosdn-cli/main.go b/cmd/gosdn-cli/main.go
index 7d5fba138033b12362ded30da3c24e7d8adcfecf..96d31c4acca436a538a715318dc85d683eb85222 100644
--- a/cmd/gosdn-cli/main.go
+++ b/cmd/gosdn-cli/main.go
@@ -2,10 +2,10 @@ package main
 
 import (
 	pb "code.fbi.h-da.de/cocsn/gosdn/api/proto"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"context"
 	"flag"
 	"fmt"
+	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 	"os"
 	"time"
diff --git a/cmd/gosdn-tview/main.go b/cmd/gosdn-tview/main.go
index 0013e46c2d91864c3d9b39fc4772d7b521247fff..8cb4d784de141462644e0edd29e379bfd7ceaf0d 100644
--- a/cmd/gosdn-tview/main.go
+++ b/cmd/gosdn-tview/main.go
@@ -8,7 +8,7 @@ import (
 	"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app"
 	grpc "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/grpc"
 	"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/views"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
+	log "github.com/sirupsen/logrus"
 )
 
 func main() {
diff --git a/cmd/gosdn/main.go b/cmd/gosdn/main.go
index 0f3e798ba397c7bfdfe4c53283e3cc95b8d5358e..7555cd65a66a644d0bdafef8e15a01257b239814 100644
--- a/cmd/gosdn/main.go
+++ b/cmd/gosdn/main.go
@@ -1,9 +1,9 @@
 package main
 
 import (
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"flag"
+	log "github.com/sirupsen/logrus"
 )
 
 func main() {
@@ -16,7 +16,7 @@ func main() {
 	flag.Parse()
 	cliSocket := *cliListenAddr + ":" + *cliListenPort
 
-	log.Loglevel(log.DEBUG)
+	log.SetLevel(log.DebugLevel)
 
 	// Setup a channel to communicate if goSDN should shutdown.
 	IsRunningChannel := make(chan bool)
diff --git a/database/client.go b/database/client.go
index 69efde8c303e1092eda2b8390fa70e6599d84c35..5910b12c7a8b60c54e6089305b348312adfff59e 100644
--- a/database/client.go
+++ b/database/client.go
@@ -1,9 +1,9 @@
 package database
 
 import (
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"errors"
 	"github.com/neo4j/neo4j-go-driver/neo4j"
+	log "github.com/sirupsen/logrus"
 )
 
 //Database is a database
diff --git a/go.mod b/go.mod
index dd2fef6f4da65fcae8b7f57e613864382958cdaf..dd79e0b9f60580331c8fb96e184c765d554ff432 100644
--- a/go.mod
+++ b/go.mod
@@ -15,6 +15,7 @@ require (
 	github.com/openconfig/ygot v0.8.7
 	github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
 	github.com/tidwall/gjson v1.6.3
+	github.com/sirupsen/logrus v1.4.2
 	golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
 	google.golang.org/grpc v1.29.1
 	google.golang.org/protobuf v1.23.0
diff --git a/go.sum b/go.sum
index 9399c8cd63a654a3b13f2bc6d19130f2babef9e1..6b90cf7a5ba559555977fa50e1c30c224c7bb174 100644
--- a/go.sum
+++ b/go.sum
@@ -245,6 +245,7 @@ github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZ
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
diff --git a/log/logger.go b/log/logger.go
deleted file mode 100644
index 9694aabe4ac0175bffc2cc424bf8b9cc782f4545..0000000000000000000000000000000000000000
--- a/log/logger.go
+++ /dev/null
@@ -1,212 +0,0 @@
-package log
-
-import (
-	"fmt"
-	"io"
-	"log/syslog"
-	"os"
-	"reflect"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-var logger *Logger
-var once sync.Once
-
-// Logger is a wrapper for log.Logger and provides
-// methods to enable and disable logging.
-type Logger struct {
-	DefaultWriter  io.Writer
-	LoglevelWriter map[Level]io.Writer
-	toSyslog       map[Level]bool
-	Loglevel       Level
-	lock           sync.Mutex
-	builder        strings.Builder
-}
-
-func (l *Logger) buildMessage(level Level, syslog bool, args ...interface{}) {
-	if !syslog {
-		l.builder.WriteString(time.Now().Format(time.RFC3339))
-	}
-	l.builder.WriteRune('\t')
-	l.builder.WriteString(prefix(level))
-	l.builder.WriteRune('\t')
-	function, line := callers()
-	functionSplitted := strings.SplitAfter(function, "/")
-	function = functionSplitted[len(functionSplitted)-1]
-	l.builder.WriteString(function)
-	l.builder.WriteRune(':')
-	l.builder.WriteString(strconv.Itoa(line))
-	l.builder.WriteRune('\t')
-	l.builder.WriteString(fmt.Sprint(args...))
-	l.builder.WriteRune('\n')
-}
-
-func get() *Logger {
-	once.Do(func() {
-		logger = &Logger{
-			DefaultWriter:  os.Stderr,
-			LoglevelWriter: make(map[Level]io.Writer),
-			toSyslog:       make(map[Level]bool),
-			Loglevel:       INFO,
-			lock:           sync.Mutex{},
-		}
-	})
-	return logger
-}
-
-// Loglevel sets the verbosity of the logger
-// Defaults to INFO
-func Loglevel(level Level) {
-	l := get()
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	l.Loglevel = level
-}
-
-// Output defines the output of the logger
-// Defaults to os.Stderr
-func Output(out io.Writer) {
-	l := get()
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	l.DefaultWriter = out
-}
-
-// LoglevelOutput defines a special output
-// for a certain log level
-func LoglevelOutput(level Level, out io.Writer) {
-	l := get()
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	l.LoglevelWriter[level] = out
-	if reflect.TypeOf(out) == reflect.TypeOf(&syslog.Writer{}) {
-		l.toSyslog[level] = true
-	}
-}
-
-// Debug passes the DEBUG flag and a
-// message to the logger
-func Debug(args ...interface{}) {
-	log(DEBUG, args...)
-}
-
-// Info passes the INFO flag and a
-// message to the logger
-func Info(args ...interface{}) {
-	log(INFO, args...)
-}
-
-// Warn passes the WARNING flag and a
-// message to the logger
-func Warn(args ...interface{}) {
-	log(WARNING, args...)
-}
-
-// Error passes the ERROR flag and a
-// message to the logger
-func Error(args ...interface{}) {
-	log(ERROR, args...)
-}
-
-// Fatal passes the FATAL flag and a
-// message to the logger and calls
-// os.Exit(1)
-func Fatal(args ...interface{}) {
-	log(FATAL, args...)
-	os.Exit(1)
-}
-
-// Debugf passes the DEBUG flag,
-// a formatted string and a
-// message to the logger
-func Debugf(format string, args ...interface{}) {
-	logf(DEBUG, format, args...)
-}
-
-// Infof passes the INFO flag,
-// a formatted string and and a
-// message to the logger
-func Infof(format string, args ...interface{}) {
-	logf(INFO, format, args...)
-}
-
-// Warnf passes the WARNING flag,
-// a formatted string and and a
-// message to the logger
-func Warnf(format string, args ...interface{}) {
-	logf(WARNING, format, args...)
-}
-
-// Errorf passes the ERROR flag,
-// a formatted string and and a
-// message to the logger
-func Errorf(format string, args ...interface{}) {
-	logf(ERROR, format, args...)
-}
-
-// Fatalf passes the FATAL flag,
-// a formatted string and and a
-// message to the logger and calls
-// os.Exit(1)
-func Fatalf(format string, args ...interface{}) {
-	logf(FATAL, format, args...)
-	os.Exit(1)
-}
-
-func logf(level Level, format string, args ...interface{}) {
-	log(level, fmt.Sprintf(format, args...))
-}
-
-func log(level Level, args ...interface{}) {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Println("Recovered in f", r)
-		}
-	}()
-	l := get()
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	defer l.builder.Reset()
-	if level <= l.Loglevel {
-		l.buildMessage(level, l.toSyslog[level], args...)
-		msg := []byte(l.builder.String())
-		writer, ok := l.LoglevelWriter[level]
-		var err error
-		if !ok {
-			_, err = l.DefaultWriter.Write(msg)
-		} else {
-			_, err = writer.Write(msg)
-		}
-		if err != nil {
-			panic(err)
-		}
-	}
-}
-
-func callers() (string, int) {
-	pc := make([]uintptr, 15)
-	n := runtime.Callers(5, pc)
-	frames := runtime.CallersFrames(pc[:n])
-	frame, _ := frames.Next()
-	return frame.Function, frame.Line
-}
-
-func prefix(level Level) string {
-	switch level {
-	case FATAL:
-		return "FATAL"
-	case ERROR:
-		return "ERROR"
-	case WARNING:
-		return "WARNING"
-	case INFO:
-		return "INFO"
-	case DEBUG:
-		return "DEBUG"
-	}
-	return ""
-}
diff --git a/log/loglevel.go b/log/loglevel.go
deleted file mode 100644
index 377e454b6c5e23b7f27fa970a28f456cd05bd33c..0000000000000000000000000000000000000000
--- a/log/loglevel.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package log
-
-// Level is an 8 bit integer representing a
-// log level for the logger
-type Level uint8
-
-// Constants for more verbose integer
-// values
-const (
-	FATAL Level = iota
-	ERROR
-	WARNING
-	INFO
-	DEBUG
-)
diff --git a/nucleus/cli-handling.go b/nucleus/cli-handling.go
index b95e9094300432d7db949dcaac9e84da5a01100e..81c11d1a8e03c68d9071f2b2df2d202397002403 100644
--- a/nucleus/cli-handling.go
+++ b/nucleus/cli-handling.go
@@ -14,8 +14,8 @@ import (
 	"sync"
 
 	pb "code.fbi.h-da.de/cocsn/gosdn/api/proto"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/sbi/restconf/client/ciena"
+	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/health"
 	healthpb "google.golang.org/grpc/health/grpc_health_v1"
@@ -120,7 +120,7 @@ func getCLIGoing(core *Core) {
 
 	//TODO: move?
 	wrt := io.MultiWriter(os.Stdout, &logBuffer)
-	log.Output(wrt)
+	log.SetOutput(wrt)
 
 	healthpb.RegisterHealthServer(cliControlServer, healthCheck)
 	pb.RegisterGrpcCliServer(cliControlServer, srv)
diff --git a/nucleus/controller.go b/nucleus/controller.go
index 5072dfbbdff572f9026e62a04a8e005c219cc3a0..7d0541f881fb8ffd86e653c220bfcef4806eb5c6 100644
--- a/nucleus/controller.go
+++ b/nucleus/controller.go
@@ -2,10 +2,10 @@ package nucleus
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/database"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces"
 	"code.fbi.h-da.de/cocsn/gosdn/sbi/restconf/client/ciena"
 	"github.com/BurntSushi/toml"
+	log "github.com/sirupsen/logrus"
 	"os"
 )
 
diff --git a/nucleus/nucleus-core.go b/nucleus/nucleus-core.go
index 0276a4ad80b52fc325373b7c8e551512e2c098f7..4e92cf46abe187399459dfb8aa5428ee450d0af0 100644
--- a/nucleus/nucleus-core.go
+++ b/nucleus/nucleus-core.go
@@ -2,8 +2,8 @@ package nucleus
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/database"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces"
+	log "github.com/sirupsen/logrus"
 	"time"
 )
 
diff --git a/sbi/restconf/client/ciena/client.go b/sbi/restconf/client/ciena/client.go
index d1c576b4ade10dd24ec44bb8081c4f2ac7c029b3..7b994496a17a145ce2b6ed5c207e0fb55b8b8435 100644
--- a/sbi/restconf/client/ciena/client.go
+++ b/sbi/restconf/client/ciena/client.go
@@ -3,7 +3,6 @@ package ciena
 import (
 	"bytes"
 	"code.fbi.h-da.de/cocsn/gosdn/database"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/interfaces"
 	"code.fbi.h-da.de/cocsn/gosdn/sbi/restconf/util"
 	apiclient "code.fbi.h-da.de/cocsn/swagger/apis/mcp/client"
@@ -15,6 +14,7 @@ import (
 	"github.com/go-openapi/strfmt"
 	"github.com/openconfig/ygot/ygot"
 	"github.com/tidwall/gjson"
+	log "github.com/sirupsen/logrus"
 	"net/http"
 	"strings"
 )