github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/logs/log.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package logs
    19  
    20  import (
    21  	"github.com/aacfactory/configures"
    22  	"github.com/aacfactory/errors"
    23  	"github.com/aacfactory/json"
    24  	"github.com/aacfactory/logs"
    25  	"strings"
    26  	"time"
    27  )
    28  
    29  type WriterConfig struct {
    30  	Name    string          `json:"name,omitempty" yaml:"name,omitempty"`
    31  	Options json.RawMessage `json:"options,omitempty" yaml:"options,omitempty"`
    32  }
    33  
    34  func (writer WriterConfig) Config() (v configures.Config, err error) {
    35  	if len(writer.Options) < 2 {
    36  		writer.Options = []byte{'{', '}'}
    37  	}
    38  	v, err = configures.NewJsonConfig(writer.Options)
    39  	return
    40  }
    41  
    42  const (
    43  	TextConsoleFormatter         = ConsoleFormatter("text")
    44  	TextColorfulConsoleFormatter = ConsoleFormatter("text_colorful")
    45  	JsonConsoleFormatter         = ConsoleFormatter("json")
    46  )
    47  
    48  type ConsoleFormatter string
    49  
    50  func (formatter ConsoleFormatter) Code() logs.ConsoleWriterFormatter {
    51  	switch formatter {
    52  	case TextColorfulConsoleFormatter:
    53  		return logs.ColorTextFormatter
    54  	case JsonConsoleFormatter:
    55  		return logs.JsonFormatter
    56  	default:
    57  		return logs.TextFormatter
    58  	}
    59  }
    60  
    61  const (
    62  	Stdout = ConsoleWriterOutType("stdout")
    63  	Stderr = ConsoleWriterOutType("stderr")
    64  	Stdmix = ConsoleWriterOutType("stdout_stderr")
    65  )
    66  
    67  type ConsoleWriterOutType string
    68  
    69  func (ot ConsoleWriterOutType) Code() logs.ConsoleWriterOutType {
    70  	switch ot {
    71  	case Stdout:
    72  		return logs.StdErr
    73  	case Stderr:
    74  		return logs.StdErr
    75  	default:
    76  		return logs.StdMix
    77  	}
    78  }
    79  
    80  const (
    81  	Debug = Level("debug")
    82  	Info  = Level("info")
    83  	Warn  = Level("warn")
    84  	Error = Level("error")
    85  )
    86  
    87  type Level string
    88  
    89  func (level Level) Code() logs.Level {
    90  	switch level {
    91  	case Debug:
    92  		return logs.DebugLevel
    93  	case Warn:
    94  		return logs.WarnLevel
    95  	case Error:
    96  		return logs.ErrorLevel
    97  	default:
    98  		return logs.InfoLevel
    99  	}
   100  }
   101  
   102  type Config struct {
   103  	Level           Level                `json:"level,omitempty" yaml:"level,omitempty"`
   104  	Formatter       ConsoleFormatter     `json:"formatter,omitempty" yaml:"formatter,omitempty"`
   105  	Console         ConsoleWriterOutType `json:"console,omitempty" yaml:"console,omitempty"`
   106  	DisableConsole  bool                 `json:"disableConsole,omitempty" yaml:"disableConsole,omitempty"`
   107  	Consumes        int                  `json:"consumes,omitempty" yaml:"consumes,omitempty"`
   108  	Buffer          int                  `json:"buffer,omitempty" yaml:"buffer,omitempty"`
   109  	SendTimeout     string               `json:"sendTimeout,omitempty" yaml:"sendTimeout,omitempty"`
   110  	ShutdownTimeout string               `json:"shutdownTimeout,omitempty" yaml:"shutdownTimeout,omitempty"`
   111  	Writers         []WriterConfig       `json:"writers,omitempty" yaml:"writer,omitempty"`
   112  }
   113  
   114  func (config *Config) GetWriter(name string) (writer configures.Config, err error) {
   115  	for _, writerConfig := range config.Writers {
   116  		if writerConfig.Name == name {
   117  			writer, err = writerConfig.Config()
   118  			return
   119  		}
   120  	}
   121  	writer, err = configures.NewJsonConfig([]byte("{}"))
   122  	return
   123  }
   124  
   125  func New(config Config, writers []Writer) (v Logger, err error) {
   126  	options := make([]logs.Option, 0, 1)
   127  	options = append(options, logs.WithLevel(config.Level.Code()))
   128  
   129  	if config.DisableConsole {
   130  		options = append(options, logs.DisableConsoleWriter())
   131  	} else {
   132  		options = append(options, logs.WithConsoleWriterOutType(config.Console.Code()))
   133  		options = append(options, logs.WithConsoleWriterFormatter(config.Formatter.Code()))
   134  	}
   135  	if consumes := config.Consumes; consumes > 0 {
   136  		options = append(options, logs.WithConsumes(consumes))
   137  	}
   138  	if buffer := config.Buffer; buffer > 0 {
   139  		options = append(options, logs.WithBuffer(buffer))
   140  	}
   141  	if sendTimeout := strings.TrimSpace(config.SendTimeout); sendTimeout != "" {
   142  		sendTimeouts, parseErr := time.ParseDuration(sendTimeout)
   143  		if parseErr != nil {
   144  			err = errors.Warning("fns: new log failed").WithCause(parseErr).WithMeta("config", "sendTimeout")
   145  			return
   146  		}
   147  		options = append(options, logs.WithSendTimeout(sendTimeouts))
   148  	}
   149  	if shutdownTimeout := strings.TrimSpace(config.ShutdownTimeout); shutdownTimeout != "" {
   150  		shutdownTimeout, parseErr := time.ParseDuration(shutdownTimeout)
   151  		if parseErr != nil {
   152  			err = errors.Warning("fns: new log failed").WithCause(parseErr).WithMeta("config", "shutdownTimeout")
   153  			return
   154  		}
   155  		options = append(options, logs.WithShutdownTimeout(shutdownTimeout))
   156  	}
   157  	if len(writers) > 0 {
   158  		for _, writer := range writers {
   159  			writerConfig, writerConfigErr := config.GetWriter(writer.Name())
   160  			if writerConfigErr != nil {
   161  				err = errors.Warning("fns: new log failed").WithCause(writerConfigErr).WithMeta("writer", writer.Name())
   162  				return
   163  			}
   164  			writerErr := writer.Construct(WriterOptions{
   165  				Config: writerConfig,
   166  			})
   167  			if writerErr != nil {
   168  				err = errors.Warning("fns: new log failed").WithCause(writerErr).WithMeta("writer", writer.Name())
   169  				return
   170  			}
   171  			options = append(options, logs.WithWriter(writer))
   172  		}
   173  	}
   174  	logger, newErr := logs.New(options...)
   175  	if newErr != nil {
   176  		err = errors.Warning("fns: new log failed").WithCause(newErr)
   177  		return
   178  	}
   179  	v = logger
   180  	return
   181  }
   182  
   183  type Logger interface {
   184  	logs.Logger
   185  }