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

lightningnetwork / lnd / 12986279612

27 Jan 2025 09:51AM UTC coverage: 57.652% (-1.1%) from 58.788%
12986279612

Pull #9447

github

yyforyongyu
sweep: rename methods for clarity

We now rename "third party" to "unknown" as the inputs can be spent via
an older sweeping tx, a third party (anchor), or a remote party (pin).
In fee bumper we don't have the info to distinguish the above cases, and
leave them to be further handled by the sweeper as it has more context.
Pull Request #9447: sweep: start tracking input spending status in the fee bumper

83 of 87 new or added lines in 2 files covered. (95.4%)

19578 existing lines in 256 files now uncovered.

103448 of 179434 relevant lines covered (57.65%)

24884.58 hits per line

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

40.71
/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 subsystem.
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.
UNCOV
32
func NewSubLoggerManager(handlers ...btclog.Handler) *SubLoggerManager {
×
UNCOV
33
        return &SubLoggerManager{
×
UNCOV
34
                loggers: make(SubLoggers),
×
UNCOV
35
                genLogger: newSubLogGenerator(
×
UNCOV
36
                        newHandlerSet(btclog.LevelInfo, handlers...),
×
UNCOV
37
                ),
×
UNCOV
38
        }
×
UNCOV
39
}
×
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,
UNCOV
45
        shutdown func()) btclog.Logger {
×
UNCOV
46

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

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

×
UNCOV
55
        r.RegisterSubLogger(subsystem, l)
×
UNCOV
56

×
UNCOV
57
        return l
×
UNCOV
58
}
×
59

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

×
UNCOV
64
        // Add the new logger to the set of loggers managed by the manager.
×
UNCOV
65
        r.mu.Lock()
×
UNCOV
66
        r.loggers[subsystem] = logger
×
UNCOV
67
        r.mu.Unlock()
×
UNCOV
68
}
×
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.
UNCOV
85
func (r *SubLoggerManager) SupportedSubsystems() []string {
×
UNCOV
86
        r.mu.Lock()
×
UNCOV
87
        defer r.mu.Unlock()
×
UNCOV
88

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

95
        // Sort the subsystems for stable display.
UNCOV
96
        sort.Strings(subsystems)
×
UNCOV
97

×
UNCOV
98
        return subsystems
×
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,
UNCOV
119
        logLevel string) {
×
UNCOV
120

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

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

×
UNCOV
130
        logger.SetLevel(level)
×
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.
UNCOV
138
func (r *SubLoggerManager) SetLogLevels(logLevel string) {
×
UNCOV
139
        r.mu.Lock()
×
UNCOV
140
        defer r.mu.Unlock()
×
UNCOV
141

×
UNCOV
142
        // Configure all sub-systems with the new logging level. Dynamically
×
UNCOV
143
        // create loggers as needed.
×
UNCOV
144
        for subsystemID := range r.loggers {
×
UNCOV
145
                r.setLogLevelUnsafe(subsystemID, logLevel)
×
UNCOV
146
        }
×
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 {
8✔
175
        // Split at the delimiter.
8✔
176
        levels := strings.Split(level, ",")
8✔
177
        if len(levels) == 0 {
8✔
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]
8✔
184
        if !strings.Contains(globalLevel, "=") {
13✔
185
                // Validate debug log level.
5✔
186
                if !validLogLevel(globalLevel) {
7✔
187
                        str := "the specified debug level [%v] is invalid"
2✔
188

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

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

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

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

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

209
                // Extract the specified subsystem and log level.
210
                fields := strings.Split(logLevelPair, "=")
6✔
211
                if len(fields) != 2 {
6✔
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]
6✔
219
                subLoggers := logger.SubLoggers()
6✔
220

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

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

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

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

240
        return nil
3✔
241
}
242

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

262
        return false
2✔
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