...

Source file src/github.com/GoogleCloudPlatform/cloudsql-proxy/logging/logging.go

Documentation: github.com/GoogleCloudPlatform/cloudsql-proxy/logging

     1  // Copyright 2015 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package logging contains helpers to support log messages. If you are using
    16  // the Cloud SQL Auth proxy as a Go library, you can override these variables to
    17  // control where log messages end up.
    18  package logging
    19  
    20  import (
    21  	"log"
    22  	"os"
    23  
    24  	"go.uber.org/zap"
    25  	"go.uber.org/zap/zapcore"
    26  )
    27  
    28  // Verbosef is called to write verbose logs, such as when a new connection is
    29  // established correctly.
    30  var Verbosef = log.Printf
    31  
    32  // Infof is called to write informational logs, such as when startup has
    33  var Infof = log.Printf
    34  
    35  // Errorf is called to write an error log, such as when a new connection fails.
    36  var Errorf = log.Printf
    37  
    38  // LogDebugToStdout updates Verbosef and Info logging to use stdout instead of stderr.
    39  func LogDebugToStdout() {
    40  	logger := log.New(os.Stdout, "", log.LstdFlags)
    41  	Verbosef = logger.Printf
    42  	Infof = logger.Printf
    43  }
    44  
    45  func noop(string, ...interface{}) {}
    46  
    47  // LogVerboseToNowhere updates Verbosef so verbose log messages are discarded
    48  func LogVerboseToNowhere() {
    49  	Verbosef = noop
    50  }
    51  
    52  // DisableLogging sets all logging levels to no-op's.
    53  func DisableLogging() {
    54  	Verbosef = noop
    55  	Infof = noop
    56  	Errorf = noop
    57  }
    58  
    59  // EnableStructuredLogs replaces all logging functions with structured logging
    60  // variants.
    61  func EnableStructuredLogs(logDebugStdout, verbose bool) (func(), error) {
    62  	// Configuration of zap is based on its Advanced Configuration example.
    63  	// See: https://pkg.go.dev/go.uber.org/zap#example-package-AdvancedConfiguration
    64  
    65  	// Define level-handling logic.
    66  	highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
    67  		return lvl >= zapcore.ErrorLevel
    68  	})
    69  	lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
    70  		return lvl < zapcore.ErrorLevel
    71  	})
    72  
    73  	// Lock wraps a WriteSyncer in a mutex to make it safe for concurrent use. In
    74  	// particular, *os.File types must be locked before use.
    75  	consoleErrors := zapcore.Lock(os.Stderr)
    76  	consoleDebugging := consoleErrors
    77  	if logDebugStdout {
    78  		consoleDebugging = zapcore.Lock(os.Stdout)
    79  	}
    80  
    81  	config := zap.NewProductionEncoderConfig()
    82  	config.LevelKey = "severity"
    83  	config.MessageKey = "message"
    84  	config.TimeKey = "timestamp"
    85  	config.EncodeLevel = zapcore.CapitalLevelEncoder
    86  	config.EncodeTime = zapcore.ISO8601TimeEncoder
    87  	consoleEncoder := zapcore.NewJSONEncoder(config)
    88  	core := zapcore.NewTee(
    89  		zapcore.NewCore(consoleEncoder, consoleErrors, highPriority),
    90  		zapcore.NewCore(consoleEncoder, consoleDebugging, lowPriority),
    91  	)
    92  	// By default, caller and stacktrace are not included, so add them here
    93  	logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
    94  
    95  	sugar := logger.Sugar()
    96  	Verbosef = sugar.Infof
    97  	if !verbose {
    98  		Verbosef = noop
    99  	}
   100  	Infof = sugar.Infof
   101  	Errorf = sugar.Errorf
   102  
   103  	return func() {
   104  		logger.Sync()
   105  	}, nil
   106  }
   107  

View as plain text