blob: c24357e3d8ea5f8fffedbf7720d00226ab3fe0b8 [file] [log] [blame]
Serge Bazanski5ade7322020-08-27 13:27:51 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package logtree
18
Serge Bazanskib0272182020-11-02 18:39:44 +010019import (
20 "fmt"
21
Serge Bazanski77cb6c52020-12-19 00:09:22 +010022 apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
Serge Bazanskib0272182020-11-02 18:39:44 +010023)
24
Serge Bazanski5ade7322020-08-27 13:27:51 +020025// LeveledLogger is a generic interface for glog-style logging. There are four hardcoded log severities, in increasing
26// order: INFO, WARNING, ERROR, FATAL. Logging at a certain severity level logs not only to consumers expecting data
27// at that severity level, but also all lower severity levels. For example, an ERROR log will also be passed to
28// consumers looking at INFO or WARNING logs.
29type LeveledLogger interface {
30 // Info logs at the INFO severity. Arguments are handled in the manner of fmt.Print, a terminating newline is added
31 // if missing.
32 Info(args ...interface{})
33 // Infof logs at the INFO severity. Arguments are handled in the manner of fmt.Printf, a terminating newline is
34 // added if missing.
35 Infof(format string, args ...interface{})
36
37 // Warning logs at the WARNING severity. Arguments are handled in the manner of fmt.Print, a terminating newline is
38 // added if missing.
39 Warning(args ...interface{})
40 // Warningf logs at the WARNING severity. Arguments are handled in the manner of fmt.Printf, a terminating newline
41 // is added if missing.
42 Warningf(format string, args ...interface{})
43
44 // Error logs at the ERROR severity. Arguments are handled in the manner of fmt.Print, a terminating newline is
45 // added if missing.
46 Error(args ...interface{})
47 // Errorf logs at the ERROR severity. Arguments are handled in the manner of fmt.Printf, a terminating newline is
48 // added if missing.
49 Errorf(format string, args ...interface{})
50
51 // Fatal logs at the FATAL severity and aborts the current program. Arguments are handled in the manner of
52 // fmt.Print, a terminating newline is added if missing.
53 Fatal(args ...interface{})
54 // Fatalf logs at the FATAL severity and aborts the current program. Arguments are handled in the manner of
55 // fmt.Printf, a terminating newline is added if missing.
56 Fatalf(format string, args ...interface{})
57
58 // V returns a VerboseLeveledLogger at a given verbosity level. These verbosity levels can be dynamically set and
59 // unset on a package-granular level by consumers of the LeveledLogger logs. The returned value represents whether
60 // logging at the given verbosity level was active at that time, and as such should not be a long-lived object
61 // in programs.
62 // This construct is further refered to as 'V-logs'.
63 V(level VerbosityLevel) VerboseLeveledLogger
64}
65
66// VerbosityLevel is a verbosity level defined for V-logs. This can be changed programmatically per Go package. When
67// logging at a given VerbosityLevel V, the current level must be equal or higher to V for the logs to be recorded.
68// Conversely, enabling a V-logging at a VerbosityLevel V also enables all logging at lower levels [Int32Min .. (V-1)].
69type VerbosityLevel int32
70
71type VerboseLeveledLogger interface {
72 // Enabled returns if this level was enabled. If not enabled, all logging into this logger will be discarded
73 // immediately.
74 // Thus, Enabled() can be used to check the verbosity level before performing any logging:
75 // if l.V(3).Enabled() { l.Info("V3 is enabled") }
76 // or, in simple cases, the convenience function .Info can be used:
77 // l.V(3).Info("V3 is enabled")
78 // The second form is shorter and more convenient, but more expensive, as its arguments are always evaluated.
79 Enabled() bool
80 // Info is the equivalent of a LeveledLogger's Info call, guarded by whether this VerboseLeveledLogger is enabled.
81 Info(args ...interface{})
82 // Infof is the equivalent of a LeveledLogger's Infof call, guarded by whether this VerboseLeveledLogger is enabled.
83 Infof(format string, args ...interface{})
84}
Serge Bazanski5faa2fc2020-09-07 14:09:30 +020085
86// Severity is one of the severities as described in LeveledLogger.
87type Severity string
88
89const (
90 INFO Severity = "I"
91 WARNING Severity = "W"
92 ERROR Severity = "E"
93 FATAL Severity = "F"
94)
95
96var (
97 // SeverityAtLeast maps a given severity to a list of severities that at that severity or higher. In other words,
98 // SeverityAtLeast[X] returns a list of severities that might be seen in a log at severity X.
99 SeverityAtLeast = map[Severity][]Severity{
100 INFO: {INFO, WARNING, ERROR, FATAL},
101 WARNING: {WARNING, ERROR, FATAL},
102 ERROR: {ERROR, FATAL},
103 FATAL: {FATAL},
104 }
105)
106
107func (s Severity) AtLeast(other Severity) bool {
108 for _, el := range SeverityAtLeast[other] {
109 if el == s {
110 return true
111 }
112 }
113 return false
114}
Serge Bazanskib0272182020-11-02 18:39:44 +0100115
116func SeverityFromProto(s apb.LeveledLogSeverity) (Severity, error) {
117 switch s {
118 case apb.LeveledLogSeverity_INFO:
119 return INFO, nil
120 case apb.LeveledLogSeverity_WARNING:
121 return WARNING, nil
122 case apb.LeveledLogSeverity_ERROR:
123 return ERROR, nil
124 case apb.LeveledLogSeverity_FATAL:
125 return FATAL, nil
126 default:
127 return "", fmt.Errorf("unknown severity value %d", s)
128 }
129}
130
131func (s Severity) ToProto() apb.LeveledLogSeverity {
132 switch s {
133 case INFO:
134 return apb.LeveledLogSeverity_INFO
135 case WARNING:
136 return apb.LeveledLogSeverity_WARNING
137 case ERROR:
138 return apb.LeveledLogSeverity_ERROR
139 case FATAL:
140 return apb.LeveledLogSeverity_FATAL
141 default:
142 return apb.LeveledLogSeverity_INVALID
143 }
144}