You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
2.7 KiB

3 years ago
package log
import (
"context"
"fmt"
3 years ago
"io"
"os"
"gitoa.ru/go-4devs/log/entry"
11 months ago
"gitoa.ru/go-4devs/log/field"
"gitoa.ru/go-4devs/log/internal/buffer"
3 years ago
)
11 months ago
// Keys for "built-in" attributes.
const (
// TimeKey is the key used by the built-in handlers for the time
// when the log method is called. The associated Value is a [time.Time].
KeyTime = "time"
// LevelKey is the key used by the built-in handlers for the level
// of the log call. The associated value is a [Level].
KeyLevel = "level"
// MessageKey is the key used by the built-in handlers for the
// message of the log call. The associated value is a string.
KeyMessage = "msg"
// SourceKey is the key used by the built-in handlers for the source file
// and line of the log call. The associated value is a string.
KeySource = "source"
)
3 years ago
11 months ago
func WithWriter(w io.Writer) func(*option) {
return func(o *option) {
o.out = w
3 years ago
}
11 months ago
}
3 years ago
11 months ago
func WithStdout() func(*option) {
return func(o *option) {
o.out = os.Stdout
3 years ago
}
}
11 months ago
// WithStringFormat sets format as simple string.
func WithStringFormat() func(*option) {
return func(o *option) {
o.format = formatText()
}
3 years ago
}
11 months ago
// WithJSONFormat sets json output format.
func WithJSONFormat() func(*option) {
return func(o *option) {
o.format = formatJSON()
3 years ago
}
}
11 months ago
type option struct {
format func(io.Writer, *entry.Entry) (int, error)
out io.Writer
3 years ago
}
11 months ago
// New creates standart logger.
func New(opts ...func(*option)) Logger {
log := option{
format: formatText(),
out: os.Stderr,
3 years ago
}
11 months ago
for _, opt := range opts {
opt(&log)
}
3 years ago
11 months ago
return func(_ context.Context, entry *entry.Entry) (int, error) {
return log.format(log.out, entry)
3 years ago
}
11 months ago
}
3 years ago
11 months ago
func formatText() func(io.Writer, *entry.Entry) (int, error) {
enc := field.NewEncoderText()
3 years ago
11 months ago
return func(w io.Writer, entry *entry.Entry) (int, error) {
buf := buffer.New()
3 years ago
defer func() {
11 months ago
buf.Free()
3 years ago
}()
11 months ago
*buf = enc.AppendField(*buf, field.String(KeyMessage, entry.Message()))
3 years ago
for _, field := range entry.Fields() {
11 months ago
*buf = enc.AppendField(*buf, field)
3 years ago
}
11 months ago
_, _ = buf.WriteString("\n")
n, err := w.Write(*buf)
if err != nil {
return 0, fmt.Errorf("format text:%w", err)
}
3 years ago
11 months ago
return n, nil
3 years ago
}
}
11 months ago
func formatJSON() func(w io.Writer, entry *entry.Entry) (int, error) {
enc := field.NewEncoderJSON()
3 years ago
11 months ago
return func(w io.Writer, entry *entry.Entry) (int, error) {
buf := buffer.New()
defer func() {
buf.Free()
}()
_, _ = buf.WriteString("{")
*buf = enc.AppendField(*buf, field.String(KeyMessage, entry.Message()))
for _, field := range entry.Fields() {
*buf = enc.AppendField(*buf, field)
}
_, _ = buf.WriteString("}")
_, _ = buf.WriteString("\n")
n, err := w.Write(*buf)
if err != nil {
return 0, fmt.Errorf("format json:%w", err)
}
return n, nil
}
3 years ago
}