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 }