浏览代码

Minor windows focused improvements (#443)

Co-authored-by: Wade Simmons <[email protected]>
Nate Brown 4 年之前
父节点
当前提交
1bc6f5fe6c
共有 4 个文件被更改,包括 95 次插入11 次删除
  1. 25 10
      Makefile
  2. 9 0
      cmd/nebula-service/logs_generic.go
  3. 54 0
      cmd/nebula-service/logs_windows.go
  4. 7 1
      cmd/nebula-service/service.go

+ 25 - 10
Makefile

@@ -1,14 +1,29 @@
 GOMINVERSION = 1.16
 NEBULA_CMD_PATH = "./cmd/nebula"
-BUILD_NUMBER ?= dev+$(shell date -u '+%Y%m%d%H%M%S')
 GO111MODULE = on
 export GO111MODULE
 
-# Ensure the version of go we are using is at least what is defined in GOMINVERSION at the top of this file
-GOVERSION := $(shell go version | awk '{print substr($$3, 3)}')
-GOISMIN := $(shell expr "$(GOVERSION)" ">=" "$(GOMINVERSION)")
-ifneq "$(GOISMIN)" "1"
-$(error "go version $(GOVERSION) is not supported, upgrade to $(GOMINVERSION) or above")
+# Set up OS specific bits
+ifeq ($(OS),Windows_NT)
+	#TODO: we should be able to ditch awk as well
+	GOVERSION := $(shell go version | awk "{print substr($$3, 3)}")
+	GOISMIN := $(shell IF "$(GOVERSION)" GEQ "$(GOMINVERSION)" ECHO 1)
+	NEBULA_CMD_SUFFIX = .exe
+	NULL_FILE = nul
+else
+	GOVERSION := $(shell go version | awk '{print substr($$3, 3)}')
+	GOISMIN := $(shell expr "$(GOVERSION)" ">=" "$(GOMINVERSION)")
+	NEBULA_CMD_SUFFIX =
+	NULL_FILE = /dev/null
+endif
+
+# Only defined the build number if we haven't already
+ifndef BUILD_NUMBER
+	ifeq ($(shell git describe --exact-match 2>$(NULL_FILE)),)
+		BUILD_NUMBER = $(shell git describe --abbrev=0 --match "v*" | cut -dv -f2)-$(shell git branch --show-current)-$(shell git describe --long --dirty | cut -d- -f2-)
+	else
+		BUILD_NUMBER = $(shell git describe --exact-match --dirty | cut -dv -f2)
+	endif
 endif
 
 LDFLAGS = -X main.Build=$(BUILD_NUMBER)
@@ -67,8 +82,8 @@ bin-freebsd: build/freebsd-amd64/nebula build/freebsd-amd64/nebula-cert
 	mv $? .
 
 bin:
-	go build $(BUILD_ARGS) -ldflags "$(LDFLAGS)" -o ./nebula ${NEBULA_CMD_PATH}
-	go build $(BUILD_ARGS) -ldflags "$(LDFLAGS)" -o ./nebula-cert ./cmd/nebula-cert
+	go build $(BUILD_ARGS) -ldflags "$(LDFLAGS)" -o ./nebula${NEBULA_CMD_SUFFIX} ${NEBULA_CMD_PATH}
+	go build $(BUILD_ARGS) -ldflags "$(LDFLAGS)" -o ./nebula-cert${NEBULA_CMD_SUFFIX} ./cmd/nebula-cert
 
 install:
 	go install $(BUILD_ARGS) -ldflags "$(LDFLAGS)" ${NEBULA_CMD_PATH}
@@ -134,10 +149,10 @@ cert/cert.pb.go: cert/cert.proto .FORCE
 	$(MAKE) -C cert cert.pb.go
 
 service:
-	@echo > /dev/null
+	@echo > $(NULL_FILE)
 	$(eval NEBULA_CMD_PATH := "./cmd/nebula-service")
 ifeq ($(words $(MAKECMDGOALS)),1)
-	$(MAKE) service ${.DEFAULT_GOAL} --no-print-directory
+	@$(MAKE) service ${.DEFAULT_GOAL} --no-print-directory
 endif
 
 bin-docker: bin build/linux-amd64/nebula build/linux-amd64/nebula-cert

+ 9 - 0
cmd/nebula-service/logs_generic.go

@@ -0,0 +1,9 @@
+// +build !windows
+
+package main
+
+import "github.com/sirupsen/logrus"
+
+func HookLogger(l *logrus.Logger) {
+	// Do nothing, let the logs flow to stdout/stderr
+}

+ 54 - 0
cmd/nebula-service/logs_windows.go

@@ -0,0 +1,54 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"github.com/kardianos/service"
+	"github.com/sirupsen/logrus"
+)
+
+// HookLogger routes the logrus logs through the service logger so that they end up in the Windows Event Viewer
+// logrus output will be discarded
+func HookLogger(l *logrus.Logger) {
+	l.AddHook(newLogHook(logger))
+	l.SetOutput(ioutil.Discard)
+}
+
+type logHook struct {
+	sl service.Logger
+}
+
+func newLogHook(sl service.Logger) *logHook {
+	return &logHook{sl: sl}
+}
+
+func (h *logHook) Fire(entry *logrus.Entry) error {
+	line, err := entry.String()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
+		return err
+	}
+
+	switch entry.Level {
+	case logrus.PanicLevel:
+		return h.sl.Error(line)
+	case logrus.FatalLevel:
+		return h.sl.Error(line)
+	case logrus.ErrorLevel:
+		return h.sl.Error(line)
+	case logrus.WarnLevel:
+		return h.sl.Warning(line)
+	case logrus.InfoLevel:
+		return h.sl.Info(line)
+	case logrus.DebugLevel:
+		return h.sl.Info(line)
+	default:
+		return nil
+	}
+}
+
+func (h *logHook) Levels() []logrus.Level {
+	return logrus.AllLevels
+}

+ 7 - 1
cmd/nebula-service/service.go

@@ -25,7 +25,7 @@ func (p *program) Start(s service.Service) error {
 	logger.Info("Nebula service starting.")
 
 	l := logrus.New()
-	l.Out = os.Stdout
+	HookLogger(l)
 
 	config := nebula.NewConfig(l)
 	err := config.Load(*p.configPath)
@@ -70,6 +70,10 @@ func doService(configPath *string, configTest *bool, build string, serviceFlag *
 		build:      build,
 	}
 
+	// Here are what the different loggers are doing:
+	// - `log` is the standard go log utility, meant to be used while the process is still attached to stdout/stderr
+	// - `logger` is the service log utility that may be attached to a special place depending on OS (Windows will have it attached to the event log)
+	// - above, in `Run` we create a `logrus.Logger` which is what nebula expects to use
 	s, err := service.New(prg, svcConfig)
 	if err != nil {
 		log.Fatal(err)
@@ -85,6 +89,7 @@ func doService(configPath *string, configTest *bool, build string, serviceFlag *
 		for {
 			err := <-errs
 			if err != nil {
+				// Route any errors from the system logger to stdout as a best effort to notice issues there
 				log.Print(err)
 			}
 		}
@@ -94,6 +99,7 @@ func doService(configPath *string, configTest *bool, build string, serviceFlag *
 	case "run":
 		err = s.Run()
 		if err != nil {
+			// Route any errors to the system logger
 			logger.Error(err)
 		}
 	default: