• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 12199391122

06 Dec 2024 01:10PM UTC coverage: 49.807% (-9.1%) from 58.933%
12199391122

push

github

web-flow
Merge pull request #9337 from Guayaba221/patch-1

chore: fix typo in ruby.md

100137 of 201051 relevant lines covered (49.81%)

2.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.43
/build/sub_logger.go
1
package build
2

3
import (
4
        "fmt"
5
        "sort"
6
        "strings"
7
        "sync"
8

9
        "github.com/btcsuite/btclog/v2"
10
)
11

12
// SubLogCreator can be used to create a new logger for a particular subsystem.
13
type SubLogCreator interface {
14
        // Logger returns a new logger for a particular subsytem.
15
        Logger(subsystemTag string) btclog.Logger
16
}
17

18
// SubLoggerManager manages a set of subsystem loggers. Level updates will be
19
// applied to all the loggers managed by the manager.
20
type SubLoggerManager struct {
21
        genLogger SubLogCreator
22

23
        loggers SubLoggers
24
        mu      sync.Mutex
25
}
26

27
// A compile time check to ensure SubLoggerManager implements the
28
// LeveledSubLogger interface.
29
var _ LeveledSubLogger = (*SubLoggerManager)(nil)
30

31
// NewSubLoggerManager constructs a new SubLoggerManager.
32
func NewSubLoggerManager(handlers ...btclog.Handler) *SubLoggerManager {
4✔
33
        return &SubLoggerManager{
4✔
34
                loggers: make(SubLoggers),
4✔
35
                genLogger: newSubLogGenerator(
4✔
36
                        newHandlerSet(btclog.LevelInfo, handlers...),
4✔
37
                ),
4✔
38
        }
4✔
39
}
4✔
40

41
// GenSubLogger creates a new sub-logger and adds it to the set managed by the
42
// SubLoggerManager. A shutdown callback function is provided to be able to shut
43
// down in case of a critical error.
44
func (r *SubLoggerManager) GenSubLogger(subsystem string,
45
        shutdown func()) btclog.Logger {
4✔
46

4✔
47
        // Create a new logger with the given subsystem tag.
4✔
48
        logger := r.genLogger.Logger(subsystem)
4✔
49

4✔
50
        // Wrap the new logger in a Shutdown logger so that the shutdown
4✔
51
        // call back is called if a critical log is ever written via this new
4✔
52
        // logger.
4✔
53
        l := NewShutdownLogger(logger, shutdown)
4✔
54

4✔
55
        r.RegisterSubLogger(subsystem, l)
4✔
56

4✔
57
        return l
4✔
58
}
4✔
59

60
// RegisterSubLogger registers the given logger under the given subsystem name.
61
func (r *SubLoggerManager) RegisterSubLogger(subsystem string,
62
        logger btclog.Logger) {
4✔
63

4✔
64
        // Add the new logger to the set of loggers managed by the manager.
4✔
65
        r.mu.Lock()
4✔
66
        r.loggers[subsystem] = logger
4✔
67
        r.mu.Unlock()
4✔
68
}
4✔
69

70
// SubLoggers returns all currently registered subsystem loggers for this log
71
// writer.
72
//
73
// NOTE: This is part of the LeveledSubLogger interface.
74
func (r *SubLoggerManager) SubLoggers() SubLoggers {
×
75
        r.mu.Lock()
×
76
        defer r.mu.Unlock()
×
77

×
78
        return r.loggers
×
79
}
×
80

81
// SupportedSubsystems returns a sorted string slice of all keys in the
82
// subsystems map, corresponding to the names of the subsystems.
83
//
84
// NOTE: This is part of the LeveledSubLogger interface.
85
func (r *SubLoggerManager) SupportedSubsystems() []string {
4✔
86
        r.mu.Lock()
4✔
87
        defer r.mu.Unlock()
4✔
88

4✔
89
        // Convert the subsystemLoggers map keys to a string slice.
4✔
90
        subsystems := make([]string, 0, len(r.loggers))
4✔
91
        for subsysID := range r.loggers {
8✔
92
                subsystems = append(subsystems, subsysID)
4✔
93
        }
4✔
94

95
        // Sort the subsystems for stable display.
96
        sort.Strings(subsystems)
4✔
97

4✔
98
        return subsystems
4✔
99
}
100

101
// SetLogLevel sets the logging level for provided subsystem. Invalid
102
// subsystems are ignored. Uninitialized subsystems are dynamically created as
103
// needed.
104
//
105
// NOTE: This is part of the LeveledSubLogger interface.
106
func (r *SubLoggerManager) SetLogLevel(subsystemID string, logLevel string) {
×
107
        r.mu.Lock()
×
108
        defer r.mu.Unlock()
×
109

×
110
        r.setLogLevelUnsafe(subsystemID, logLevel)
×
111
}
×
112

113
// setLogLevelUnsafe sets the logging level for provided subsystem. Invalid
114
// subsystems are ignored. Uninitialized subsystems are dynamically created as
115
// needed.
116
//
117
// NOTE: the SubLoggerManager mutex must be held before calling this method.
118
func (r *SubLoggerManager) setLogLevelUnsafe(subsystemID string,
119
        logLevel string) {
4✔
120

4✔
121
        // Ignore invalid subsystems.
4✔
122
        logger, ok := r.loggers[subsystemID]
4✔
123
        if !ok {
4✔
124
                return
×
125
        }
×
126

127
        // Defaults to info if the log level is invalid.
128
        level, _ := btclog.LevelFromString(logLevel)
4✔
129

4✔
130
        logger.SetLevel(level)
4✔
131
}
132

133
// SetLogLevels sets the log level for all subsystem loggers to the passed
134
// level. It also dynamically creates the subsystem loggers as needed, so it
135
// can be used to initialize the logging system.
136
//
137
// NOTE: This is part of the LeveledSubLogger interface.
138
func (r *SubLoggerManager) SetLogLevels(logLevel string) {
4✔
139
        r.mu.Lock()
4✔
140
        defer r.mu.Unlock()
4✔
141

4✔
142
        // Configure all sub-systems with the new logging level. Dynamically
4✔
143
        // create loggers as needed.
4✔
144
        for subsystemID := range r.loggers {
8✔
145
                r.setLogLevelUnsafe(subsystemID, logLevel)
4✔
146
        }
4✔
147
}
148

149
// SubLoggers is a type that holds a map of subsystem loggers keyed by their
150
// subsystem name.
151
type SubLoggers map[string]btclog.Logger
152

153
// LeveledSubLogger provides the ability to retrieve the subsystem loggers of
154
// a logger and set their log levels individually or all at once.
155
type LeveledSubLogger interface {
156
        // SubLoggers returns the map of all registered subsystem loggers.
157
        SubLoggers() SubLoggers
158

159
        // SupportedSubsystems returns a slice of strings containing the names
160
        // of the supported subsystems. Should ideally correspond to the keys
161
        // of the subsystem logger map and be sorted.
162
        SupportedSubsystems() []string
163

164
        // SetLogLevel assigns an individual subsystem logger a new log level.
165
        SetLogLevel(subsystemID string, logLevel string)
166

167
        // SetLogLevels assigns all subsystem loggers the same new log level.
168
        SetLogLevels(logLevel string)
169
}
170

171
// ParseAndSetDebugLevels attempts to parse the specified debug level and set
172
// the levels accordingly on the given logger. An appropriate error is returned
173
// if anything is invalid.
174
func ParseAndSetDebugLevels(level string, logger LeveledSubLogger) error {
4✔
175
        // Split at the delimiter.
4✔
176
        levels := strings.Split(level, ",")
4✔
177
        if len(levels) == 0 {
4✔
178
                return fmt.Errorf("invalid log level: %v", level)
×
179
        }
×
180

181
        // If the first entry has no =, treat is as the log level for all
182
        // subsystems.
183
        globalLevel := levels[0]
4✔
184
        if !strings.Contains(globalLevel, "=") {
8✔
185
                // Validate debug log level.
4✔
186
                if !validLogLevel(globalLevel) {
4✔
187
                        str := "the specified debug level [%v] is invalid"
×
188

×
189
                        return fmt.Errorf(str, globalLevel)
×
190
                }
×
191

192
                // Change the logging level for all subsystems.
193
                logger.SetLogLevels(globalLevel)
4✔
194

4✔
195
                // The rest will target specific subsystems.
4✔
196
                levels = levels[1:]
4✔
197
        }
198

199
        // Go through the subsystem/level pairs while detecting issues and
200
        // update the log levels accordingly.
201
        for _, logLevelPair := range levels {
4✔
202
                if !strings.Contains(logLevelPair, "=") {
×
203
                        str := "the specified debug level contains an " +
×
204
                                "invalid subsystem/level pair [%v]"
×
205

×
206
                        return fmt.Errorf(str, logLevelPair)
×
207
                }
×
208

209
                // Extract the specified subsystem and log level.
210
                fields := strings.Split(logLevelPair, "=")
×
211
                if len(fields) != 2 {
×
212
                        str := "the specified debug level has an invalid " +
×
213
                                "format [%v] -- use format subsystem1=level1," +
×
214
                                "subsystem2=level2"
×
215

×
216
                        return fmt.Errorf(str, logLevelPair)
×
217
                }
×
218
                subsysID, logLevel := fields[0], fields[1]
×
219
                subLoggers := logger.SubLoggers()
×
220

×
221
                // Validate subsystem.
×
222
                if _, exists := subLoggers[subsysID]; !exists {
×
223
                        str := "the specified subsystem [%v] is invalid -- " +
×
224
                                "supported subsystems are %v"
×
225

×
226
                        return fmt.Errorf(
×
227
                                str, subsysID, logger.SupportedSubsystems(),
×
228
                        )
×
229
                }
×
230

231
                // Validate log level.
232
                if !validLogLevel(logLevel) {
×
233
                        str := "the specified debug level [%v] is invalid"
×
234
                        return fmt.Errorf(str, logLevel)
×
235
                }
×
236

237
                logger.SetLogLevel(subsysID, logLevel)
×
238
        }
239

240
        return nil
4✔
241
}
242

243
// validLogLevel returns whether or not logLevel is a valid debug log level.
244
func validLogLevel(logLevel string) bool {
4✔
245
        switch logLevel {
4✔
246
        case "trace":
×
247
                fallthrough
×
248
        case "debug":
4✔
249
                fallthrough
4✔
250
        case "info":
4✔
251
                fallthrough
4✔
252
        case "warn":
4✔
253
                fallthrough
4✔
254
        case "error":
4✔
255
                fallthrough
4✔
256
        case "critical":
4✔
257
                fallthrough
4✔
258
        case "off":
4✔
259
                return true
4✔
260
        }
261

262
        return false
×
263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc