package common import ( "fmt" "io" "time" ) type Logger interface { LogPlainError(err error) (int, error) LogError(str string, fmt ...any) (int, error) Log(str string, fmt ...any) (int, error) } type StdoutLogging struct { Id uint Stdout, Stderr io.StringWriter Date time.Time } var id uint func CreateStdoutLogger(stdout io.StringWriter, stderr io.StringWriter) Logger { id++ log := &StdoutLogging{ Id: id, Stdout: stdout, Stderr: stderr, Date: time.Now(), } return log } func prepareMsg(time time.Duration, id uint, str string, params ...any) string { var allParams []any = []any{ id, time.String(), } allParams = append(allParams, params...) return fmt.Sprintf("[%x] [%s]: "+str+"\n", allParams...) } func (s *StdoutLogging) LogPlainError(err error) (int, error) { return s.Stderr.WriteString(prepareMsg(time.Since(s.Date), s.Id, "%#v\n", err)) } func (s *StdoutLogging) LogError(str string, params ...any) (int, error) { return s.Stderr.WriteString(prepareMsg(time.Since(s.Date),s.Id, str, params...)) } func (s *StdoutLogging) Log(str string, params ...any) (int, error) { return s.Stdout.WriteString(prepareMsg(time.Since(s.Date), s.Id, str, params...)) } type LoggingWriteCloser struct { err bool *StdoutLogging } func (l *LoggingWriteCloser) Write(data []byte) (int, error) { if l.err { return l.LogError("%s", data) } return l.Log("%s", data) } func (l *LoggingWriteCloser) Close() error { return nil } func (s *StdoutLogging) CreateLogWriter(err bool) io.WriteCloser { logger := new(LoggingWriteCloser) logger.StdoutLogging = s logger.err = err return logger }