istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/util/clog/clog.go (about)

     1  // Copyright Istio Authors
     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 clog
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"os"
    21  
    22  	"istio.io/istio/pkg/log"
    23  )
    24  
    25  // Logger provides optional log taps for console and test buffer outputs.
    26  type Logger interface {
    27  	LogAndPrint(v ...any)
    28  	LogAndError(v ...any)
    29  	LogAndFatal(a ...any)
    30  	LogAndPrintf(format string, a ...any)
    31  	LogAndErrorf(format string, a ...any)
    32  	LogAndFatalf(format string, a ...any)
    33  	Print(s string)
    34  	PrintErr(s string)
    35  }
    36  
    37  // ConsoleLogger is the struct used for mesh command
    38  type ConsoleLogger struct {
    39  	stdOut io.Writer
    40  	stdErr io.Writer
    41  	scope  *log.Scope
    42  }
    43  
    44  // NewConsoleLogger creates a new logger and returns a pointer to it.
    45  // stdOut and stdErr can be used to capture output for testing. If scope is nil, the default scope is used.
    46  func NewConsoleLogger(stdOut, stdErr io.Writer, scope *log.Scope) *ConsoleLogger {
    47  	s := scope
    48  	if s == nil {
    49  		s = log.RegisterScope(log.DefaultScopeName, log.DefaultScopeName)
    50  	}
    51  	return &ConsoleLogger{
    52  		stdOut: stdOut,
    53  		stdErr: stdErr,
    54  		scope:  s,
    55  	}
    56  }
    57  
    58  // NewDefaultLogger creates a new logger that outputs to stdout/stderr at default scope.
    59  func NewDefaultLogger() *ConsoleLogger {
    60  	return NewConsoleLogger(os.Stdout, os.Stderr, nil)
    61  }
    62  
    63  func (l *ConsoleLogger) LogAndPrint(v ...any) {
    64  	if len(v) == 0 {
    65  		return
    66  	}
    67  	s := fmt.Sprint(v...)
    68  	l.Print(s + "\n")
    69  	l.scope.Infof(s)
    70  }
    71  
    72  func (l *ConsoleLogger) LogAndError(v ...any) {
    73  	if len(v) == 0 {
    74  		return
    75  	}
    76  	s := fmt.Sprint(v...)
    77  	l.PrintErr(s + "\n")
    78  	l.scope.Infof(s)
    79  }
    80  
    81  func (l *ConsoleLogger) LogAndFatal(a ...any) {
    82  	l.LogAndError(a...)
    83  	os.Exit(-1)
    84  }
    85  
    86  func (l *ConsoleLogger) LogAndPrintf(format string, a ...any) {
    87  	s := fmt.Sprintf(format, a...)
    88  	l.Print(s + "\n")
    89  	l.scope.Infof(s)
    90  }
    91  
    92  func (l *ConsoleLogger) LogAndErrorf(format string, a ...any) {
    93  	s := fmt.Sprintf(format, a...)
    94  	l.PrintErr(s + "\n")
    95  	l.scope.Infof(s)
    96  }
    97  
    98  func (l *ConsoleLogger) LogAndFatalf(format string, a ...any) {
    99  	l.LogAndErrorf(format, a...)
   100  	os.Exit(-1)
   101  }
   102  
   103  func (l *ConsoleLogger) Print(s string) {
   104  	_, _ = l.stdOut.Write([]byte(s))
   105  }
   106  
   107  func (l *ConsoleLogger) PrintErr(s string) {
   108  	_, _ = l.stdErr.Write([]byte(s))
   109  }