mirror of
https://github.com/goharbor/harbor
synced 2025-04-19 22:57:59 +00: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