internal/log/log.go (69 lines of code) (raw):

// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package log import ( "io" llog "log" "os" "github.com/GoogleCloudPlatform/alloydb-auth-proxy/alloydb" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) // StdLogger is the standard logger that distinguishes between info and error // logs. type StdLogger struct { infoLog *llog.Logger debugLog *llog.Logger errLog *llog.Logger } // NewStdLogger create a Logger that uses out and err for informational and // error messages. func NewStdLogger(out, err io.Writer) alloydb.Logger { return &StdLogger{ infoLog: llog.New(out, "", llog.LstdFlags), debugLog: llog.New(out, "", llog.LstdFlags), errLog: llog.New(err, "", llog.LstdFlags), } } // Infof logs informational messages. func (l *StdLogger) Infof(format string, v ...interface{}) { l.infoLog.Printf(format, v...) } // Errorf logs error messages. func (l *StdLogger) Errorf(format string, v ...interface{}) { l.errLog.Printf(format, v...) } // Debugf logs debug messages. func (l *StdLogger) Debugf(format string, v ...interface{}) { l.debugLog.Printf(format, v...) } // StructuredLogger writes log messages in JSON. type StructuredLogger struct { logger *zap.SugaredLogger } // Infof logs informational messages. func (l *StructuredLogger) Infof(format string, v ...interface{}) { l.logger.Infof(format, v...) } // Errorf logs error messages. func (l *StructuredLogger) Errorf(format string, v ...interface{}) { l.logger.Errorf(format, v...) } // Debugf logs debug messages. func (l *StructuredLogger) Debugf(format string, v ...interface{}) { l.logger.Debugf(format, v...) } // NewStructuredLogger creates a Logger that logs messages using JSON. func NewStructuredLogger(quiet bool) (alloydb.Logger, func() error) { // Configure structured logs to adhere to LogEntry format // https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry c := zap.NewProductionEncoderConfig() c.LevelKey = "severity" c.MessageKey = "message" c.TimeKey = "timestamp" c.EncodeLevel = zapcore.CapitalLevelEncoder c.EncodeTime = zapcore.ISO8601TimeEncoder enc := zapcore.NewJSONEncoder(c) var syncer zapcore.WriteSyncer // quiet disables writing to the info log if quiet { syncer = zapcore.AddSync(io.Discard) } else { syncer = zapcore.Lock(os.Stdout) } core := zapcore.NewTee( zapcore.NewCore(enc, syncer, zap.LevelEnablerFunc(func(l zapcore.Level) bool { // Anything below error, goes to the info log. return l < zapcore.ErrorLevel })), zapcore.NewCore(enc, zapcore.Lock(os.Stderr), zap.LevelEnablerFunc(func(l zapcore.Level) bool { // Anything at error or higher goes to the error log. return l >= zapcore.ErrorLevel })), ) l := &StructuredLogger{ logger: zap.New(core).Sugar(), } return l, l.logger.Sync }