diff --git a/build/ci/.documentation-ci.yml b/build/ci/.documentation-ci.yml
index 23a5caf7f43f0601939a1740e3ca3803d37ae007..76e5303f163a2a7f5e0206dba6bfe2d938218433 100644
--- a/build/ci/.documentation-ci.yml
+++ b/build/ci/.documentation-ci.yml
@@ -11,7 +11,7 @@ documentation:pdf:
       - documentation/design/*.md
   script:
   - cd documentation/design
-  - pandoc --filter pandoc-citeproc --bibliography=bibliography.bib --csl=acm-sig-proceedings.csl
+  - pandoc --citeproc --bibliography=bibliography.bib --csl=acm-sig-proceedings.csl
     --variable papersize=a4paper -s *.md -o documentation.pdf
   artifacts:
     paths:
diff --git a/cmd/gosdn-tview/app/app.go b/cmd/gosdn-tview/app/app.go
index 037c1adc771ed4a092241a9930b5bb0ba30e4279..3570285c4b481c7608b6490c345cf3d9c20dc2cb 100644
--- a/cmd/gosdn-tview/app/app.go
+++ b/cmd/gosdn-tview/app/app.go
@@ -1,5 +1,6 @@
 package app
 
+//TODO: App should be a Singleton i guess
 import (
 	"github.com/rivo/tview"
 )
@@ -56,6 +57,11 @@ func (a *App) Draw() {
 	a.app.Draw()
 }
 
+//QueueUpdateDraw calls tview.QueueUpdateDraw()
+func (a *App) QueueUpdateDraw(f func()) {
+	a.app.QueueUpdateDraw(f)
+}
+
 //SetFocus sets the focus on new tview.Primitive
 func (a *App) SetFocus(v tview.Primitive) {
 	a.app.SetFocus(v)
diff --git a/cmd/gosdn-tview/grpc/commands.go b/cmd/gosdn-tview/grpc/commands.go
index 5b0c0790601164401d30bd6a39d86377627e355a..10ba4652b2016af91c839b42f0ef07d7a2b4acbe 100644
--- a/cmd/gosdn-tview/grpc/commands.go
+++ b/cmd/gosdn-tview/grpc/commands.go
@@ -1,13 +1,17 @@
 package commands
 
 import (
-	pb "code.fbi.h-da.de/cocsn/gosdn/api/proto"
-	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"context"
+	"time"
+
+	pb "code.fbi.h-da.de/cocsn/gosdn/api/proto"
+	"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app"
 	"github.com/rivo/tview"
 	grpc "google.golang.org/grpc"
+	//Package google.golang.org/grpc/health is needed to make gRPC Health Check work
+	_ "google.golang.org/grpc/health"
+	healthpb "google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/protobuf/types/known/emptypb"
-	"time"
 )
 
 const (
@@ -30,18 +34,32 @@ var CommandList = []command{
 	{"shutdown", "request controller to shutdown", goSDNShutdown},
 }
 
+var serviceConfig = `{
+	"loadBalancingPolicy": "round_robin",
+	"healthCheckConfig": {
+		"serviceName": ""
+	}
+}`
+
 //Connect creates a new connection to the gRPC server
 func Connect(address string) (*grpc.ClientConn, error) {
-	return grpc.Dial(address, grpc.WithInsecure(), grpc.WithTimeout(5*time.Second), grpc.WithBlock())
+	options := []grpc.DialOption{
+		grpc.WithInsecure(),
+		grpc.WithBlock(),
+		grpc.WithDefaultServiceConfig(serviceConfig),
+		grpc.WithTimeout(5 * time.Second),
+	}
+
+	return grpc.Dial(address, options...)
 }
 
 //GoSDNLogStream creates a continuous gRPC stream to recieve goSDN logs
-func GoSDNLogStream(conn *grpc.ClientConn, clv *tview.TextView) error {
+func GoSDNLogStream(app *app.App, conn *grpc.ClientConn, tv *tview.TextView) error {
 	var streamError error
 	c := pb.NewGrpcCliClient(conn)
 	stream, err := c.CreateLogStream(context.Background(), &emptypb.Empty{})
 	if err != nil {
-		log.Error(err)
+		return err
 	}
 
 	go func(stream pb.GrpcCli_CreateLogStreamClient) {
@@ -49,10 +67,23 @@ func GoSDNLogStream(conn *grpc.ClientConn, clv *tview.TextView) error {
 			msg, err := stream.Recv()
 			if err != nil {
 				streamError = err
+
+				go func() {
+					ticker := time.NewTicker(5 * time.Second)
+					for range ticker.C {
+						if err := GoSDNLogStream(app, conn, tv); err == nil {
+							ticker.Stop()
+							return
+						}
+					}
+				}()
+
 				break
 			}
 			response := []byte(msg.Log)
-			clv.Write(response)
+			app.QueueUpdateDraw(func() {
+				tv.Write(response)
+			})
 		}
 	}(stream)
 
@@ -68,11 +99,55 @@ func goSDNSayHello(conn *grpc.ClientConn) string {
 	defer cancel()
 	r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
 	if err != nil {
-		log.Fatal(err)
+		return err.Error()
 	}
+
 	return r.GetMessage()
 }
 
+//WatchHealth continuous gRPC Health Check stream to recieve health changes
+func WatchHealth(service string, app *app.App, conn *grpc.ClientConn, tv *tview.TextView) error {
+	var streamError error
+
+	c := healthpb.NewHealthClient(conn)
+	stream, err := c.Watch(context.Background(), &healthpb.HealthCheckRequest{Service: service})
+	if err != nil {
+		app.QueueUpdateDraw(func() {
+			tv.Clear()
+			tv.SetText(err.Error())
+		})
+		return err
+	}
+
+	go func(stream healthpb.Health_WatchClient) {
+		for {
+			msg, err := stream.Recv()
+			if err != nil {
+				streamError = err
+				go func() {
+					ticker := time.NewTicker(5 * time.Second)
+					for range ticker.C {
+						if err := WatchHealth(service, app, conn, tv); err == nil {
+							ticker.Stop()
+							return
+						}
+					}
+				}()
+
+				break
+			}
+
+			app.QueueUpdateDraw(func() {
+				tv.Clear()
+				tv.SetText(msg.GetStatus().String())
+			})
+
+		}
+	}(stream)
+
+	return streamError
+}
+
 func goSDNShutdown(conn *grpc.ClientConn) string {
 
 	c := pb.NewGrpcCliClient(conn)
@@ -83,7 +158,7 @@ func goSDNShutdown(conn *grpc.ClientConn) string {
 	defer cancel()
 	r, err := c.Shutdown(ctx, &pb.ShutdownRequest{Name: name})
 	if err != nil {
-		log.Fatal(err)
+		return err.Error()
 	}
 	return r.GetMessage()
 }
@@ -105,7 +180,7 @@ func TAPIGetEdge(conn *grpc.ClientConn) string {
 	defer cancel()
 	r, err := c.TAPIGetEdge(ctx, &pb.TAPIRequest{Name: name})
 	if err != nil {
-		log.Fatal(err)
+		return err.Error()
 	}
 	return r.GetMessage()
 }
@@ -121,7 +196,7 @@ func TAPIGetEdgeNode(conn *grpc.ClientConn) string {
 	defer cancel()
 	r, err := c.TAPIGetEdgeNode(ctx, &pb.TAPIRequest{Name: name})
 	if err != nil {
-		log.Fatal(err)
+		return err.Error()
 	}
 	return r.GetMessage()
 }
@@ -138,7 +213,7 @@ func TAPIGetLink(conn *grpc.ClientConn) string {
 	defer cancel()
 	r, err := c.TAPIGetLink(ctx, &pb.TAPIRequest{Name: name})
 	if err != nil {
-		log.Fatal(err)
+		return err.Error()
 	}
 	return r.GetMessage()
 }
diff --git a/cmd/gosdn-tview/main.go b/cmd/gosdn-tview/main.go
index 4191524b856526f9d6d13cd2fb3db654127a80f9..0013e46c2d91864c3d9b39fc4772d7b521247fff 100644
--- a/cmd/gosdn-tview/main.go
+++ b/cmd/gosdn-tview/main.go
@@ -18,7 +18,6 @@ func main() {
 
 	addr := strings.Join([]string{*addrIPv4, strconv.Itoa(*port)}, ":")
 	conn, err := grpc.Connect(addr)
-
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/cmd/gosdn-tview/views/consoleLogView.go b/cmd/gosdn-tview/views/consoleLogView.go
index 0c7769d2ae61d6e4fb1a5dc15fce4832fd025e95..35af59cdad223200f66ce041c3f406305d4a9bfa 100644
--- a/cmd/gosdn-tview/views/consoleLogView.go
+++ b/cmd/gosdn-tview/views/consoleLogView.go
@@ -1,6 +1,7 @@
 package views
 
 import (
+	"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app"
 	commands "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/grpc"
 	"github.com/rivo/tview"
 	"google.golang.org/grpc"
@@ -13,7 +14,7 @@ type ConsoleLogView struct {
 }
 
 //NewConsoleLogView creates a new ConsoleLogView
-func NewConsoleLogView(title string, conn *grpc.ClientConn) *ConsoleLogView {
+func NewConsoleLogView(title string, app *app.App, conn *grpc.ClientConn) *ConsoleLogView {
 	clv := &ConsoleLogView{
 		consoleLogView: tview.NewTextView(),
 		title:          title,
@@ -26,7 +27,7 @@ func NewConsoleLogView(title string, conn *grpc.ClientConn) *ConsoleLogView {
 		SetBorder(true).
 		SetTitle(clv.title)
 
-	commands.GoSDNLogStream(conn, clv.consoleLogView)
+	commands.GoSDNLogStream(app, conn, clv.consoleLogView)
 
 	return clv
 }
diff --git a/cmd/gosdn-tview/views/gRPCStatusView.go b/cmd/gosdn-tview/views/gRPCStatusView.go
index 836c06a167173fe23f283a6dcfc04edfb7dd47b0..a4d9df9e65f9908b7e21ddc5fdd20ece2da34982 100644
--- a/cmd/gosdn-tview/views/gRPCStatusView.go
+++ b/cmd/gosdn-tview/views/gRPCStatusView.go
@@ -2,9 +2,9 @@ package views
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/app"
+	commands "code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn-tview/grpc"
 	"github.com/rivo/tview"
 	"google.golang.org/grpc"
-	"time"
 )
 
 //GRPCStatusView is an application view to display the current status of
@@ -26,13 +26,7 @@ func NewGRPCStatusView(app *app.App, conn *grpc.ClientConn) *GRPCStatusView {
 		SetBorder(true).
 		SetTitle("gRPC")
 
-	//TODO: gRPCs Health Check looks like a way better alternative here!
-	//--> no app.Draw() required anymore
-	sv.gRPCStatusView.SetChangedFunc(func() {
-		app.Draw()
-	})
-
-	go gRPCTicker(sv, conn)
+	commands.WatchHealth("", app, conn, sv.gRPCStatusView)
 
 	return sv
 }
@@ -47,19 +41,3 @@ func (sv *GRPCStatusView) SetContent(s string) {
 	sv.gRPCStatusView.Clear()
 	sv.gRPCStatusView.SetText(s)
 }
-
-func gRPCTicker(sv *GRPCStatusView, conn *grpc.ClientConn) {
-	sv.SetContent(checkStatus(conn))
-	//TODO: refactor -> get rid of hardcoded values
-	ticker := time.NewTicker(5 * time.Second)
-	for range ticker.C {
-		sv.SetContent(checkStatus(conn))
-	}
-}
-
-func checkStatus(conn *grpc.ClientConn) string {
-	if str := conn.GetState().String(); str == "READY" || str == "IDLE" {
-		return "[green]" + "connected"
-	}
-	return "[red]" + "disconnected"
-}
diff --git a/cmd/gosdn-tview/views/resultAndInputView.go b/cmd/gosdn-tview/views/resultAndInputView.go
index ff012a0f6e045afbc40708b96e5a04d3373c336d..5b83868c2accdcca59146ad5178f3413167c4d33 100644
--- a/cmd/gosdn-tview/views/resultAndInputView.go
+++ b/cmd/gosdn-tview/views/resultAndInputView.go
@@ -24,7 +24,7 @@ func NewResultAndInputView(title string, app *app.App, commandListView tview.Pri
 		pages:          tview.NewPages(),
 		pndInputView:   NewAddPNDView("add PND", app),
 		resultView:     tview.NewTextView(),
-		consoleLogView: NewConsoleLogView("logs", conn),
+		consoleLogView: NewConsoleLogView("logs", app, conn),
 	}
 	rv.resultView.
 		SetDynamicColors(true).
diff --git a/configs/gosdn.toml b/configs/gosdn.toml
index a66664646568ef38ca747be1f6fa359fb88eb3f9..b0ba9553705d34d970728f39669bb770e252487b 100644
--- a/configs/gosdn.toml
+++ b/configs/gosdn.toml
@@ -1,4 +1,3 @@
-# example config
 CliSocket = "localhost:55055"
 DatabaseSocket = "bolt://172.17.0.4:7687"
 DatabaseUser = ""
diff --git a/nucleus/cli-handling.go b/nucleus/cli-handling.go
index f4e41b78f31ebf950e1b1b8a84c2938038dbcbe7..b95e9094300432d7db949dcaac9e84da5a01100e 100644
--- a/nucleus/cli-handling.go
+++ b/nucleus/cli-handling.go
@@ -17,6 +17,8 @@ import (
 	"code.fbi.h-da.de/cocsn/gosdn/log"
 	"code.fbi.h-da.de/cocsn/gosdn/sbi/restconf/client/ciena"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/health"
+	healthpb "google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/protobuf/types/known/emptypb"
 )
 
@@ -99,8 +101,11 @@ func (s *server) Shutdown(ctx context.Context, in *pb.ShutdownRequest) (*pb.Shut
 
 func getCLIGoing(core *Core) {
 
-	var logConnections []*logConnection
-	var logBuffer buf
+	var (
+		logConnections []*logConnection
+		logBuffer      buf
+		system         = ""
+	)
 
 	log.Info("Starting: GetCLIGoing")
 	// Boot-up the control interface for the cli
@@ -110,14 +115,18 @@ func getCLIGoing(core *Core) {
 	}
 
 	cliControlServer := grpc.NewServer()
+	healthCheck := health.NewServer()
 	srv = &server{core: core, logConnections: logConnections}
 
 	//TODO: move?
 	wrt := io.MultiWriter(os.Stdout, &logBuffer)
 	log.Output(wrt)
 
+	healthpb.RegisterHealthServer(cliControlServer, healthCheck)
 	pb.RegisterGrpcCliServer(cliControlServer, srv)
 
+	healthCheck.SetServingStatus(system, healthpb.HealthCheckResponse_SERVING)
+
 	if err := cliControlServer.Serve(cliControlListener); err != nil {
 		log.Fatal(err)
 	}