Skip to content

Commit 6afb0d6

Browse files
committed
Enhance logging interface
1 parent c0ea180 commit 6afb0d6

File tree

16 files changed

+660
-55
lines changed

16 files changed

+660
-55
lines changed

Makefile

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,23 @@ ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
3333

3434
default: build
3535

36-
check:
36+
.PHONY: help
37+
help:
38+
@grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
39+
40+
vet: ## Go vet
3741
go vet ./...
38-
golint $$(go list ./...) 2>&1
42+
43+
check: vet
3944
gosec ./... 2>&1
4045

41-
test:
46+
lint: ## Lint
47+
golint $$(go list ./...) 2>&1
48+
49+
test: ## Test
4250
GO111MODULE=on go test -mod=vendor -v ./...
4351

44-
build:
52+
build: vet ## Build executable
4553
CGO_ENABLED=1 GO111MODULE=on go build -mod=vendor -o $(BINARY) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" .
4654

4755
.PHONY: os-build
@@ -58,10 +66,10 @@ docker-push:
5866
docker tag $(LOCAL_IMAGE) $(CLOUD_IMAGE)
5967
docker push $(CLOUD_IMAGE)
6068

61-
fmt:
69+
fmt: ## Go format
6270
go fmt ./...
6371

64-
clean:
72+
clean: ## Clean
6573
@rm -rf $(BINARY)
6674
@rm -rf $(CHART_PKG)
6775

@@ -70,15 +78,15 @@ deps:
7078
GO111MODULE=on go get ./...
7179

7280
.PHONY: vendor
73-
vendor:
81+
vendor: ## Go vendor
7482
GO111MODULE=on go mod vendor
7583

7684
.PHONY: tidy
77-
tidy:
85+
tidy: ## Go tidy
7886
GO111MODULE=on go mod tidy
7987

8088
.PHONY: tag
81-
tag:
89+
tag: ## Git tag
8290
git tag $(TAG)
8391

8492
.PHONY: release-setup
@@ -97,29 +105,32 @@ release-snapshot: helm-package
97105

98106

99107
.PHONY: helm-package
100-
helm-package:
108+
helm-package: ## Package helm chart
101109
$(HELM_BIN) package $(ROOT_DIR)/charts/mqtt-proxy --app-version $(TAG) --version $(CHART_VERSION) --destination $(ROOT_DIR)/$(CHART_PKG)
102110
mv $(ROOT_DIR)/$(CHART_PKG)/mqtt-proxy-$(CHART_VERSION).tgz $(ROOT_DIR)/$(CHART_PKG)/mqtt-proxy-$(CHART_VERSION)-chart.tgz
103111
$(HELM_BIN) repo index $(ROOT_DIR)/$(CHART_PKG) --url https://grepplabs.github.io/mqtt-proxy
104112
# TODO: --merge old_charts_dir/index.yaml
105113

106114
.PHONY: helm-template
107-
helm-template:
115+
helm-template: ## Template helm chart
108116
$(HELM_BIN) template $(SVC_NAME) $(ROOT_DIR)/charts/mqtt-proxy \
109117
-f $(ROOT_DIR)/charts/mqtt-proxy/values-$(HELM_VALUES).yaml \
110118
--namespace=$(SVC_NAMESPACE)
111119

112120
.PHONY: helm-install
113-
helm-install:
121+
helm-install: ## Install helm chart
114122
$(HELM_BIN) upgrade $(SVC_NAME) $(ROOT_DIR)/charts/mqtt-proxy \
115123
-f $(ROOT_DIR)/charts/mqtt-proxy/values-$(HELM_VALUES).yaml \
116124
--namespace=$(SVC_NAMESPACE) \
117125
--install \
118126
--create-namespace
119127

120128
.PHONY: helm-test
121-
helm-test:
129+
helm-test: ## Test helm chart
122130
$(HELM_BIN) test $(SVC_NAME) \
123131
--namespace=$(SVC_NAMESPACE)
124132

125133

134+
.PHONY: install-tools
135+
install-tools: ## Install tools
136+
go install github.com/securego/gosec/v2/cmd/gosec@latest

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ MQTT Proxy allows MQTT clients to send messages to other messaging systems
2525
* [ ] Others
2626
* [x] Helm chart
2727
* [ ] Server certificate rotation
28-
28+
* [ ] Self sign / intermediate certificates
29+
* [ ] Let's Encrypt certificates
30+
* [ ] HashiCorp Vault certificates
31+
* [ ] K8S cert-manager
32+
33+
2934
### Install binary release
3035

3136
1. Download the latest Linux release

cmd/root.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/oklog/run"
1212
"github.com/pkg/errors"
1313
"github.com/prometheus/client_golang/prometheus"
14+
"github.com/prometheus/client_golang/prometheus/collectors"
1415
"github.com/prometheus/common/version"
1516
"go.uber.org/automaxprocs/maxprocs"
1617
"gopkg.in/alecthomas/kingpin.v2"
@@ -24,7 +25,7 @@ func Execute() {
2425
app.Version(version.Print("mqtt-proxy"))
2526
app.HelpFlag.Short('h')
2627

27-
logConfig := log.Configuration{}
28+
logConfig := log.LogConfig{}
2829
app.Flag("log.level", "Log filtering One of: [fatal, error, warn, info, debug]").Default(log.Info).EnumVar(&logConfig.LogLevel, log.Fatal, log.Error, log.Warn, log.Info, log.Debug)
2930
app.Flag("log.format", "Log format to use. One of: [logfmt, json, plain]").Default(log.LogFormatLogfmt).EnumVar(&logConfig.LogFormat, log.LogFormatLogfmt, log.LogFormatJson, log.LogFormatPlain)
3031
app.Flag("log.field-name.time", "Log time field name").Default(log.TimeKey).StringVar(&logConfig.LogFieldNames.Time)
@@ -45,6 +46,7 @@ func Execute() {
4546
}
4647

4748
logger := log.NewLogger(logConfig)
49+
log.InitInstance(logger)
4850

4951
undo, err := maxprocs.Set(maxprocs.Logger(func(template string, args ...interface{}) {
5052
logger.Debugf(template, args...)
@@ -59,10 +61,11 @@ func Execute() {
5961
metrics := prometheus.NewRegistry()
6062
metrics.MustRegister(
6163
version.NewCollector("mqtt_proxy"),
62-
prometheus.NewGoCollector(),
63-
prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}),
64+
collectors.NewGoCollector(
65+
collectors.WithGoCollectorRuntimeMetrics(),
66+
),
67+
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
6468
)
65-
6669
var g run.Group
6770

6871
if err := cmds[cmd](&g, logger, metrics); err != nil {

pkg/log/logger.go

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package log
22

3+
import (
4+
"context"
5+
"sync"
6+
)
7+
38
//Fields Type to pass when we want to call WithFields for structured logging
49
type Fields map[string]interface{}
510

@@ -40,20 +45,39 @@ const (
4045
LogFormatLogfmt = "logfmt"
4146
)
4247

48+
const (
49+
// ContextLogTag is used to identifier fields, which should be appended to a log entry, from a passed context
50+
ContextLogTag string = "logging"
51+
)
52+
4353
//Logger is our contract for the logger
4454
type Logger interface {
55+
Print(message string)
56+
4557
Printf(format string, args ...interface{})
4658

59+
Debug(message string)
60+
4761
Debugf(format string, args ...interface{})
4862

63+
Info(message string)
64+
4965
Infof(format string, args ...interface{})
5066

67+
Warn(message string)
68+
5169
Warnf(format string, args ...interface{})
5270

71+
Error(message string)
72+
5373
Errorf(format string, args ...interface{})
5474

75+
Panic(message string)
76+
5577
Panicf(format string, args ...interface{})
5678

79+
Fatal(message string)
80+
5781
Fatalf(format string, args ...interface{})
5882

5983
WithFields(keyValues Fields) Logger
@@ -73,6 +97,8 @@ type Logger interface {
7397
IsPanic() bool
7498

7599
IsFatal() bool
100+
101+
WithContext(context context.Context) Logger
76102
}
77103

78104
type LogFieldNames struct {
@@ -83,29 +109,48 @@ type LogFieldNames struct {
83109
Error string
84110
}
85111

86-
// Configuration stores the config for the logger
87-
type Configuration struct {
112+
// LogConfig stores the config for the logger
113+
type LogConfig struct {
88114
LogFormat string
89115
LogLevel string
90116
LogFieldNames LogFieldNames
91117
}
92118

93119
//NewLogger returns an instance of logger
94-
func NewLogger(config Configuration) Logger {
120+
func NewLogger(config LogConfig) Logger {
95121
return newZapLogger(config)
96122
}
97123

98-
var DefaultLogger = NewDefaultLogger()
124+
var (
125+
instance Logger
126+
once sync.Once
127+
)
128+
129+
//InitInstance initialize logger which will be returned by GetInstance
130+
func InitInstance(logger Logger) {
131+
once.Do(func() {
132+
instance = logger
133+
})
134+
}
135+
136+
func GetInstance() Logger {
137+
once.Do(func() {
138+
if instance == nil {
139+
instance = NewDefaultLogger()
140+
}
141+
})
142+
return instance
143+
}
99144

100145
//NewDefaultLogger returns an instance of logger with default parameters
101146
func NewDefaultLogger() Logger {
102-
config := Configuration{
147+
config := LogConfig{
103148
LogFormat: LogFormatLogfmt,
104149
LogLevel: Info,
105150
}
106151
return newZapLogger(config)
107152
}
108153

109154
func Printf(format string, args ...interface{}) {
110-
DefaultLogger.Printf(format, args...)
155+
GetInstance().Printf(format, args...)
111156
}

pkg/log/zap.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package log
22

33
import (
4+
"context"
45
"os"
56

67
"github.com/sykesm/zap-logfmt"
@@ -14,7 +15,7 @@ type zapLogger struct {
1415
errorKey string
1516
}
1617

17-
func getEncoder(config Configuration) zapcore.Encoder {
18+
func getEncoder(config LogConfig) zapcore.Encoder {
1819
encoderConfig := zap.NewProductionEncoderConfig()
1920
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
2021
encoderConfig.TimeKey = getStringOrDefault(config.LogFieldNames.Time, TimeKey)
@@ -59,7 +60,7 @@ func getZapLevel(level string) zapcore.Level {
5960
}
6061
}
6162

62-
func newZapLogger(config Configuration) Logger {
63+
func newZapLogger(config LogConfig) Logger {
6364
cores := []zapcore.Core{}
6465

6566
level := getZapLevel(config.LogLevel)
@@ -83,6 +84,10 @@ func newZapLogger(config Configuration) Logger {
8384
}
8485
}
8586

87+
func (l *zapLogger) Debug(message string) {
88+
l.sugaredLogger.Debug(message)
89+
}
90+
8691
func (l *zapLogger) Debugf(format string, args ...interface{}) {
8792
l.sugaredLogger.Debugf(format, args...)
8893
}
@@ -95,6 +100,14 @@ func (l *zapLogger) Printf(format string, args ...interface{}) {
95100
l.sugaredLogger.Infof(format, args...)
96101
}
97102

103+
func (l *zapLogger) Print(message string) {
104+
l.sugaredLogger.Info(message)
105+
}
106+
107+
func (l *zapLogger) Info(message string) {
108+
l.sugaredLogger.Info(message)
109+
}
110+
98111
func (l *zapLogger) Infof(format string, args ...interface{}) {
99112
l.sugaredLogger.Infof(format, args...)
100113
}
@@ -103,6 +116,10 @@ func (l *zapLogger) IsInfo() bool {
103116
return l.level <= zapcore.InfoLevel
104117
}
105118

119+
func (l *zapLogger) Warn(message string) {
120+
l.sugaredLogger.Warn(message)
121+
}
122+
106123
func (l *zapLogger) Warnf(format string, args ...interface{}) {
107124
l.sugaredLogger.Warnf(format, args...)
108125
}
@@ -111,6 +128,10 @@ func (l *zapLogger) IsWarn() bool {
111128
return l.level <= zapcore.WarnLevel
112129
}
113130

131+
func (l *zapLogger) Error(message string) {
132+
l.sugaredLogger.Errorf(message)
133+
}
134+
114135
func (l *zapLogger) Errorf(format string, args ...interface{}) {
115136
l.sugaredLogger.Errorf(format, args...)
116137
}
@@ -119,6 +140,10 @@ func (l *zapLogger) IsError() bool {
119140
return l.level <= zapcore.ErrorLevel
120141
}
121142

143+
func (l *zapLogger) Fatal(message string) {
144+
l.sugaredLogger.Fatal(message)
145+
}
146+
122147
func (l *zapLogger) Fatalf(format string, args ...interface{}) {
123148
l.sugaredLogger.Fatalf(format, args...)
124149
}
@@ -127,6 +152,10 @@ func (l *zapLogger) IsFatal() bool {
127152
return l.level <= zapcore.FatalLevel
128153
}
129154

155+
func (l *zapLogger) Panic(message string) {
156+
l.sugaredLogger.Panic(message)
157+
}
158+
130159
func (l *zapLogger) Panicf(format string, args ...interface{}) {
131160
l.sugaredLogger.Panicf(format, args...)
132161
}
@@ -155,3 +184,15 @@ func (l *zapLogger) WithError(err error) Logger {
155184
}
156185
return l.WithFields(Fields{l.errorKey: err.Error()})
157186
}
187+
188+
func (l *zapLogger) WithContext(ctx context.Context) Logger {
189+
fields := ctx.Value(ContextLogTag)
190+
if fields == nil {
191+
return l
192+
}
193+
maps := fields.(Fields)
194+
if len(maps) > 0 {
195+
return l.WithFields(maps)
196+
}
197+
return l
198+
}

0 commit comments

Comments
 (0)