File: logr.go

package info (click to toggle)
golang-golang-x-exp 0.0~git20231006.7918f67-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 6,492 kB
  • sloc: ansic: 1,900; objc: 276; sh: 272; asm: 48; makefile: 27
file content (104 lines) | stat: -rw-r--r-- 2,759 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package logr is a logr implementation that uses events.
package logr

import (
	"context"

	"github.com/go-logr/logr"
	"golang.org/x/exp/event"
	"golang.org/x/exp/event/severity"
)

type logSink struct {
	ev        *event.Event // cloned, never delivered
	labels    []event.Label
	nameSep   string
	name      string
	verbosity int
}

func NewLogger(ctx context.Context, nameSep string) logr.Logger {
	return logr.New(&logSink{
		ev:      event.New(ctx, event.LogKind),
		nameSep: nameSep,
	})
}

func (*logSink) Init(logr.RuntimeInfo) {}

// WithName implements logr.LogSink.WithName.
func (l *logSink) WithName(name string) logr.LogSink {
	l2 := *l
	if l.name == "" {
		l2.name = name
	} else {
		l2.name = l.name + l.nameSep + name
	}
	return &l2
}

// Enabled tests whether this LogSink is enabled at the specified V-level.
// For example, commandline flags might be used to set the logging
// verbosity and disable some info logs.
func (l *logSink) Enabled(level int) bool {
	return true
}

// Info implements logr.LogSink.Info.
func (l *logSink) Info(level int, msg string, keysAndValues ...interface{}) {
	if l.ev == nil {
		return
	}
	ev := l.ev.Clone()
	ev.Labels = append(ev.Labels, convertVerbosity(level).Label())
	l.log(ev, msg, keysAndValues)
}

// Error implements logr.LogSink.Error.
func (l *logSink) Error(err error, msg string, keysAndValues ...interface{}) {
	if l.ev == nil {
		return
	}
	ev := l.ev.Clone()
	ev.Labels = append(ev.Labels, event.Value("error", err))
	l.log(ev, msg, keysAndValues)
}

func (l *logSink) log(ev *event.Event, msg string, keysAndValues []interface{}) {
	ev.Labels = append(ev.Labels)
	ev.Labels = append(ev.Labels, l.labels...)
	for i := 0; i < len(keysAndValues); i += 2 {
		ev.Labels = append(ev.Labels, newLabel(keysAndValues[i], keysAndValues[i+1]))
	}
	ev.Labels = append(ev.Labels,
		event.String("name", l.name),
		event.String("msg", msg),
	)
	ev.Deliver()
}

// WithValues implements logr.LogSink.WithValues.
func (l *logSink) WithValues(keysAndValues ...interface{}) logr.LogSink {
	l2 := *l
	if len(keysAndValues) > 0 {
		l2.labels = make([]event.Label, len(l.labels), len(l.labels)+(len(keysAndValues)/2))
		copy(l2.labels, l.labels)
		for i := 0; i < len(keysAndValues); i += 2 {
			l2.labels = append(l2.labels, newLabel(keysAndValues[i], keysAndValues[i+1]))
		}
	}
	return &l2
}

func newLabel(key, value interface{}) event.Label {
	return event.Value(key.(string), value)
}

func convertVerbosity(v int) severity.Level {
	//TODO: this needs to be more complicated, v decreases with increasing severity
	return severity.Level(v)
}