mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-22 08:38:03 +01:00
commit
2ee1e0a2a0
21
log/formatter.go
Normal file
21
log/formatter.go
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
// Formatter formats records in different ways: text, json, etc.
|
||||
type Formatter interface {
|
||||
Format(*Record) ([]byte, error)
|
||||
}
|
75
log/level.go
Normal file
75
log/level.go
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Level ...
|
||||
type Level int
|
||||
|
||||
const (
|
||||
// DebugLevel debug
|
||||
DebugLevel Level = iota
|
||||
// InfoLevel info
|
||||
InfoLevel
|
||||
// WarningLevel warning
|
||||
WarningLevel
|
||||
// ErrorLevel error
|
||||
ErrorLevel
|
||||
// FatalLevel fatal
|
||||
FatalLevel
|
||||
)
|
||||
|
||||
func (l Level) string() (lvl string) {
|
||||
switch l {
|
||||
case DebugLevel:
|
||||
lvl = "DEBUG"
|
||||
case InfoLevel:
|
||||
lvl = "INFO"
|
||||
case WarningLevel:
|
||||
lvl = "WARNING"
|
||||
case ErrorLevel:
|
||||
lvl = "ERROR"
|
||||
case FatalLevel:
|
||||
lvl = "FATAL"
|
||||
default:
|
||||
lvl = "UNKNOWN"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func parseLevel(lvl string) (level Level, err error) {
|
||||
|
||||
switch lvl {
|
||||
case "debug":
|
||||
level = DebugLevel
|
||||
case "info":
|
||||
level = InfoLevel
|
||||
case "warning":
|
||||
level = WarningLevel
|
||||
case "error":
|
||||
level = ErrorLevel
|
||||
case "fatal":
|
||||
level = FatalLevel
|
||||
default:
|
||||
err = fmt.Errorf("invalid log level: %s", lvl)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
263
log/logger.go
Normal file
263
log/logger.go
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var logger = New(os.Stdout, NewTextFormatter(), WarningLevel)
|
||||
|
||||
func init() {
|
||||
// TODO add item in configuaration file
|
||||
lvl := os.Getenv("LOG_LEVEL")
|
||||
if len(lvl) == 0 {
|
||||
logger.SetLevel(InfoLevel)
|
||||
return
|
||||
}
|
||||
|
||||
level, err := parseLevel(lvl)
|
||||
if err != nil {
|
||||
logger.SetLevel(InfoLevel)
|
||||
return
|
||||
}
|
||||
|
||||
logger.SetLevel(level)
|
||||
|
||||
}
|
||||
|
||||
// Logger provides a struct with fields that describe the details of logger.
|
||||
type Logger struct {
|
||||
out io.Writer
|
||||
fmtter Formatter
|
||||
lvl Level
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// New returns a customized Logger
|
||||
func New(out io.Writer, fmtter Formatter, lvl Level) *Logger {
|
||||
return &Logger{
|
||||
out: out,
|
||||
fmtter: fmtter,
|
||||
lvl: lvl,
|
||||
}
|
||||
}
|
||||
|
||||
//SetOutput sets the output of Logger l
|
||||
func (l *Logger) SetOutput(out io.Writer) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
l.out = out
|
||||
}
|
||||
|
||||
//SetFormatter sets the formatter of Logger l
|
||||
func (l *Logger) SetFormatter(fmtter Formatter) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
l.fmtter = fmtter
|
||||
}
|
||||
|
||||
//SetLevel sets the level of Logger l
|
||||
func (l *Logger) SetLevel(lvl Level) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
l.lvl = lvl
|
||||
}
|
||||
|
||||
//SetOutput sets the output of default Logger
|
||||
func SetOutput(out io.Writer) {
|
||||
logger.SetOutput(out)
|
||||
}
|
||||
|
||||
//SetFormatter sets the formatter of default Logger
|
||||
func SetFormatter(fmtter Formatter) {
|
||||
logger.SetFormatter(fmtter)
|
||||
}
|
||||
|
||||
//SetLevel sets the level of default Logger
|
||||
func SetLevel(lvl Level) {
|
||||
logger.SetLevel(lvl)
|
||||
}
|
||||
|
||||
func (l *Logger) output(record *Record) (err error) {
|
||||
b, err := l.fmtter.Format(record)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
_, err = l.out.Write(b)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Debug ...
|
||||
func (l *Logger) Debug(v ...interface{}) {
|
||||
if l.lvl <= DebugLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprint(v...), line, DebugLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugf ...
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
if l.lvl <= DebugLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprintf(format, v...), line, DebugLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Info ...
|
||||
func (l *Logger) Info(v ...interface{}) {
|
||||
if l.lvl <= InfoLevel {
|
||||
record := NewRecord(time.Now(), fmt.Sprint(v...), "", InfoLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Infof ...
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
if l.lvl <= InfoLevel {
|
||||
record := NewRecord(time.Now(), fmt.Sprintf(format, v...), "", InfoLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Warning ...
|
||||
func (l *Logger) Warning(v ...interface{}) {
|
||||
if l.lvl <= WarningLevel {
|
||||
record := NewRecord(time.Now(), fmt.Sprint(v...), "", WarningLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Warningf ...
|
||||
func (l *Logger) Warningf(format string, v ...interface{}) {
|
||||
if l.lvl <= WarningLevel {
|
||||
record := NewRecord(time.Now(), fmt.Sprintf(format, v...), "", WarningLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Error ...
|
||||
func (l *Logger) Error(v ...interface{}) {
|
||||
if l.lvl <= ErrorLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprint(v...), line, ErrorLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf ...
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
if l.lvl <= ErrorLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprintf(format, v...), line, ErrorLevel)
|
||||
l.output(record)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatal ...
|
||||
func (l *Logger) Fatal(v ...interface{}) {
|
||||
if l.lvl <= FatalLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprint(v...), line, FatalLevel)
|
||||
l.output(record)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Fatalf ...
|
||||
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
||||
if l.lvl <= FatalLevel {
|
||||
line := line(2)
|
||||
record := NewRecord(time.Now(), fmt.Sprintf(format, v...), line, FatalLevel)
|
||||
l.output(record)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Debug ...
|
||||
func Debug(v ...interface{}) {
|
||||
logger.Debug(v...)
|
||||
}
|
||||
|
||||
// Debugf ...
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
logger.Debugf(format, v...)
|
||||
}
|
||||
|
||||
// Info ...
|
||||
func Info(v ...interface{}) {
|
||||
logger.Info(v...)
|
||||
}
|
||||
|
||||
// Infof ...
|
||||
func Infof(format string, v ...interface{}) {
|
||||
logger.Infof(format, v...)
|
||||
}
|
||||
|
||||
// Warning ...
|
||||
func Warning(v ...interface{}) {
|
||||
logger.Warning(v...)
|
||||
}
|
||||
|
||||
// Warningf ...
|
||||
func Warningf(format string, v ...interface{}) {
|
||||
logger.Warningf(format, v...)
|
||||
}
|
||||
|
||||
// Error ...
|
||||
func Error(v ...interface{}) {
|
||||
logger.Error(v...)
|
||||
}
|
||||
|
||||
// Errorf ...
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
logger.Errorf(format, v...)
|
||||
}
|
||||
|
||||
// Fatal ...
|
||||
func Fatal(v ...interface{}) {
|
||||
logger.Fatal(v...)
|
||||
}
|
||||
|
||||
// Fatalf ...
|
||||
func Fatalf(format string, v ...interface{}) {
|
||||
logger.Fatalf(format, v...)
|
||||
}
|
||||
|
||||
func line(calldepth int) string {
|
||||
_, file, line, ok := runtime.Caller(calldepth)
|
||||
if !ok {
|
||||
file = "???"
|
||||
line = 0
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%d", file, line)
|
||||
}
|
38
log/record.go
Normal file
38
log/record.go
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Record holds information about log
|
||||
type Record struct {
|
||||
Time time.Time // time when the log produced
|
||||
Msg string // content of the log
|
||||
Line string // in which file and line that the log produced
|
||||
Lvl Level // level of the log
|
||||
}
|
||||
|
||||
// NewRecord creates a record according to the arguments provided and returns it
|
||||
func NewRecord(time time.Time, msg, line string, lvl Level) *Record {
|
||||
return &Record{
|
||||
Time: time,
|
||||
Msg: msg,
|
||||
Line: line,
|
||||
Lvl: lvl,
|
||||
}
|
||||
}
|
63
log/textformatter.go
Normal file
63
log/textformatter.go
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var defaultTimeFormat = time.RFC3339 // 2006-01-02T15:04:05Z07:00
|
||||
|
||||
// TextFormatter represents a kind of formatter that formats the logs as plain text
|
||||
type TextFormatter struct {
|
||||
timeFormat string
|
||||
}
|
||||
|
||||
// NewTextFormatter returns a TextFormatter, the format of time is time.RFC3339
|
||||
func NewTextFormatter() *TextFormatter {
|
||||
return &TextFormatter{
|
||||
timeFormat: defaultTimeFormat,
|
||||
}
|
||||
}
|
||||
|
||||
// Format formats the logs as "time [level] line message"
|
||||
func (t *TextFormatter) Format(r *Record) (b []byte, err error) {
|
||||
s := fmt.Sprintf("%s [%s] ", r.Time.Format(t.timeFormat), r.Lvl.string())
|
||||
|
||||
if len(r.Line) != 0 {
|
||||
s = s + r.Line + " "
|
||||
}
|
||||
|
||||
if len(r.Msg) != 0 {
|
||||
s = s + r.Msg
|
||||
}
|
||||
|
||||
b = []byte(s)
|
||||
|
||||
if len(b) == 0 || b[len(b)-1] != '\n' {
|
||||
b = append(b, '\n')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetTimeFormat sets time format of TextFormatter if the parameter fmt is not null
|
||||
func (t *TextFormatter) SetTimeFormat(fmt string) {
|
||||
if len(fmt) != 0 {
|
||||
t.timeFormat = fmt
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user