*: reflow comments to 80 characters
This reformats the entire Metropolis codebase to have comments no longer
than 80 characters, implementing CR/66.
This has been done half manually, as we don't have a good integration
between commentwrap/Bazel, but that can be implemented if we decide to
go for this tool/limit.
Change-Id: If1fff0b093ef806f5dc00551c11506e8290379d0
diff --git a/metropolis/pkg/logtree/journal.go b/metropolis/pkg/logtree/journal.go
index 78c55a1..d29fdaa 100644
--- a/metropolis/pkg/logtree/journal.go
+++ b/metropolis/pkg/logtree/journal.go
@@ -22,18 +22,20 @@
"sync"
)
-// DN is the Distinguished Name, a dot-delimited path used to address loggers within a LogTree. For example, "foo.bar"
-// designates the 'bar' logger node under the 'foo' logger node under the root node of the logger. An empty string is
-// the root node of the tree.
+// DN is the Distinguished Name, a dot-delimited path used to address loggers
+// within a LogTree. For example, "foo.bar" designates the 'bar' logger node
+// under the 'foo' logger node under the root node of the logger. An empty
+// string is the root node of the tree.
type DN string
var (
ErrInvalidDN = errors.New("invalid DN")
)
-// Path return the parts of a DN, ie. all the elements of the dot-delimited DN path. For the root node, an empty list
-// will be returned. An error will be returned if the DN is invalid (contains empty parts, eg. `foo..bar`, `.foo` or
-// `foo.`.
+// Path return the parts of a DN, ie. all the elements of the dot-delimited DN
+// path. For the root node, an empty list will be returned. An error will be
+// returned if the DN is invalid (contains empty parts, eg. `foo..bar`, `.foo`
+// or `foo.`.
func (d DN) Path() ([]string, error) {
if d == "" {
return nil, nil
@@ -47,12 +49,14 @@
return parts, nil
}
-// journal is the main log recording structure of logtree. It manages linked lists containing the actual log entries,
-// and implements scans across them. It does not understand the hierarchical nature of logtree, and instead sees all
-// entries as part of a global linked list and a local linked list for a given DN.
+// journal is the main log recording structure of logtree. It manages linked lists
+// containing the actual log entries, and implements scans across them. It does not
+// understand the hierarchical nature of logtree, and instead sees all entries as
+// part of a global linked list and a local linked list for a given DN.
//
-// The global linked list is represented by the head/tail pointers in journal and nextGlobal/prevGlobal pointers in
-// entries. The local linked lists are represented by heads[DN]/tails[DN] pointers in journal and nextLocal/prevLocal
+// The global linked list is represented by the head/tail pointers in journal and
+// nextGlobal/prevGlobal pointers in entries. The local linked lists are
+// represented by heads[DN]/tails[DN] pointers in journal and nextLocal/prevLocal
// pointers in entries:
//
// .------------. .------------. .------------.
@@ -70,37 +74,42 @@
// | | |
// ( head ) ( tails[Z] ) ( tail )
// ( heads[A.B] ) ( heads[Z] ) ( tails[A.B] )
-//
type journal struct {
- // mu locks the rest of the structure. It must be taken during any operation on the journal.
+ // mu locks the rest of the structure. It must be taken during any operation on the
+ // journal.
mu sync.RWMutex
- // tail is the side of the global linked list that contains the newest log entry, ie. the one that has been pushed
- // the most recently. It can be nil when no log entry has yet been pushed. The global linked list contains all log
- // entries pushed to the journal.
+ // tail is the side of the global linked list that contains the newest log entry,
+ // ie. the one that has been pushed the most recently. It can be nil when no log
+ // entry has yet been pushed. The global linked list contains all log entries
+ // pushed to the journal.
tail *entry
- // head is the side of the global linked list that contains the oldest log entry. It can be nil when no log entry
- // has yet been pushed.
+ // head is the side of the global linked list that contains the oldest log entry.
+ // It can be nil when no log entry has yet been pushed.
head *entry
- // tails are the tail sides of a local linked list for a given DN, ie. the sides that contain the newest entry. They
- // are nil if there are no log entries for that DN.
+ // tails are the tail sides of a local linked list for a given DN, ie. the sides
+ // that contain the newest entry. They are nil if there are no log entries for that
+ // DN.
tails map[DN]*entry
- // heads are the head sides of a local linked list for a given DN, ie. the sides that contain the oldest entry. They
- // are nil if there are no log entries for that DN.
+ // heads are the head sides of a local linked list for a given DN, ie. the sides
+ // that contain the oldest entry. They are nil if there are no log entries for that
+ // DN.
heads map[DN]*entry
- // quota is a map from DN to quota structure, representing the quota policy of a particular DN-designated logger.
+ // quota is a map from DN to quota structure, representing the quota policy of a
+ // particular DN-designated logger.
quota map[DN]*quota
- // subscribers are observer to logs. New log entries get emitted to channels present in the subscriber structure,
- // after filtering them through subscriber-provided filters (eg. to limit events to subtrees that interest that
- // particular subscriber).
+ // subscribers are observer to logs. New log entries get emitted to channels
+ // present in the subscriber structure, after filtering them through subscriber-
+ // provided filters (eg. to limit events to subtrees that interest that particular
+ // subscriber).
subscribers []*subscriber
}
-// newJournal creates a new empty journal. All journals are independent from eachother, and as such, all LogTrees are
-// also independent.
+// newJournal creates a new empty journal. All journals are independent from
+// eachother, and as such, all LogTrees are also independent.
func newJournal() *journal {
return &journal{
tails: make(map[DN]*entry),
@@ -110,7 +119,8 @@
}
}
-// filter is a predicate that returns true if a log subscriber or reader is interested in a given log entry.
+// filter is a predicate that returns true if a log subscriber or reader is
+// interested in a given log entry.
type filter func(*entry) bool
// filterAll returns a filter that accepts all log entries.
@@ -118,16 +128,18 @@
return func(*entry) bool { return true }
}
-// filterExact returns a filter that accepts only log entries at a given exact DN. This filter should not be used in
-// conjunction with journal.scanEntries - instead, journal.getEntries should be used, as it is much faster.
+// filterExact returns a filter that accepts only log entries at a given exact
+// DN. This filter should not be used in conjunction with journal.scanEntries
+// - instead, journal.getEntries should be used, as it is much faster.
func filterExact(dn DN) filter {
return func(e *entry) bool {
return e.origin == dn
}
}
-// filterSubtree returns a filter that accepts all log entries at a given DN and sub-DNs. For example, filterSubtree at
-// "foo.bar" would allow entries at "foo.bar", "foo.bar.baz", but not "foo" or "foo.barr".
+// filterSubtree returns a filter that accepts all log entries at a given DN and
+// sub-DNs. For example, filterSubtree at "foo.bar" would allow entries at
+// "foo.bar", "foo.bar.baz", but not "foo" or "foo.barr".
func filterSubtree(root DN) filter {
if root == "" {
return filterAll()
@@ -150,8 +162,9 @@
}
}
-// filterSeverity returns a filter that accepts log entries at a given severity level or above. See the Severity type
-// for more information about severity levels.
+// filterSeverity returns a filter that accepts log entries at a given severity
+// level or above. See the Severity type for more information about severity
+// levels.
func filterSeverity(atLeast Severity) filter {
return func(e *entry) bool {
return e.leveled != nil && e.leveled.severity.AtLeast(atLeast)
@@ -166,10 +179,11 @@
return e.leveled != nil
}
-// scanEntries does a linear scan through the global entry list and returns all entries that match the given filters. If
-// retrieving entries for an exact event, getEntries should be used instead, as it will leverage DN-local linked lists
-// to retrieve them faster.
-// journal.mu must be taken at R or RW level when calling this function.
+// scanEntries does a linear scan through the global entry list and returns all
+// entries that match the given filters. If retrieving entries for an exact event,
+// getEntries should be used instead, as it will leverage DN-local linked lists to
+// retrieve them faster. journal.mu must be taken at R or RW level when calling
+// this function.
func (j *journal) scanEntries(filters ...filter) (res []*entry) {
cur := j.tail
for {
@@ -191,10 +205,12 @@
}
}
-// getEntries returns all entries at a given DN. This is faster than a scanEntries(filterExact), as it uses the special
-// local linked list pointers to traverse the journal. Additional filters can be passed to further limit the entries
-// returned, but a scan through this DN's local linked list will be performed regardless.
-// journal.mu must be taken at R or RW level when calling this function.
+// getEntries returns all entries at a given DN. This is faster than a
+// scanEntries(filterExact), as it uses the special local linked list pointers to
+// traverse the journal. Additional filters can be passed to further limit the
+// entries returned, but a scan through this DN's local linked list will be
+// performed regardless. journal.mu must be taken at R or RW level when calling
+// this function.
func (j *journal) getEntries(exact DN, filters ...filter) (res []*entry) {
cur := j.tails[exact]
for {
diff --git a/metropolis/pkg/logtree/journal_entry.go b/metropolis/pkg/logtree/journal_entry.go
index d81b687..d51d406 100644
--- a/metropolis/pkg/logtree/journal_entry.go
+++ b/metropolis/pkg/logtree/journal_entry.go
@@ -18,43 +18,49 @@
import "source.monogon.dev/metropolis/pkg/logbuffer"
-// entry is a journal entry, representing a single log event (encompassed in a Payload) at a given DN.
-// See the journal struct for more information about the global/local linked lists.
+// entry is a journal entry, representing a single log event (encompassed in a
+// Payload) at a given DN. See the journal struct for more information about the
+// global/local linked lists.
type entry struct {
- // origin is the DN at which the log entry was recorded, or conversely, in which DN it will be available at.
+ // origin is the DN at which the log entry was recorded, or conversely, in which DN
+ // it will be available at.
origin DN
- // journal is the parent journal of this entry. An entry can belong only to a single journal. This pointer is used
- // to mutate the journal's head/tail pointers when unlinking an entry.
+ // journal is the parent journal of this entry. An entry can belong only to a
+ // single journal. This pointer is used to mutate the journal's head/tail pointers
+ // when unlinking an entry.
journal *journal
- // leveled is the leveled log entry for this entry, if this log entry was emitted by leveled logging. Otherwise it
- // is nil.
+ // leveled is the leveled log entry for this entry, if this log entry was emitted
+ // by leveled logging. Otherwise it is nil.
leveled *LeveledPayload
- // raw is the raw log entry for this entry, if this log entry was emitted by raw logging. Otherwise it is nil.
+ // raw is the raw log entry for this entry, if this log entry was emitted by raw
+ // logging. Otherwise it is nil.
raw *logbuffer.Line
- // prevGlobal is the previous entry in the global linked list, or nil if this entry is the oldest entry in the
- // global linked list.
+ // prevGlobal is the previous entry in the global linked list, or nil if this entry
+ // is the oldest entry in the global linked list.
prevGlobal *entry
- // nextGlobal is the next entry in the global linked list, or nil if this entry is the newest entry in the global
- // linked list.
+ // nextGlobal is the next entry in the global linked list, or nil if this entry is
+ // the newest entry in the global linked list.
nextGlobal *entry
- // prevLocal is the previous entry in this entry DN's local linked list, or nil if this entry is the oldest entry in
- // this local linked list.
+ // prevLocal is the previous entry in this entry DN's local linked list, or nil if
+ // this entry is the oldest entry in this local linked list.
prevLocal *entry
- // prevLocal is the next entry in this entry DN's local linked list, or nil if this entry is the newest entry in
- // this local linked list.
+ // prevLocal is the next entry in this entry DN's local linked list, or nil if this
+ // entry is the newest entry in this local linked list.
nextLocal *entry
- // seqLocal is a counter within a local linked list that increases by one each time a new log entry is added. It is
- // used to quickly establish local linked list sizes (by subtracting seqLocal from both ends). This setup allows for
- // O(1) length calculation for local linked lists as long as entries are only unlinked from the head or tail (which
- // is the case in the current implementation).
+ // seqLocal is a counter within a local linked list that increases by one each time
+ // a new log entry is added. It is used to quickly establish local linked list
+ // sizes (by subtracting seqLocal from both ends). This setup allows for O(1)
+ // length calculation for local linked lists as long as entries are only unlinked
+ // from the head or tail (which is the case in the current implementation).
seqLocal uint64
}
-// external returns a LogEntry object for this entry, ie. the public version of this object, without fields relating to
-// the parent journal, linked lists, sequences, etc. These objects are visible to library consumers.
+// external returns a LogEntry object for this entry, ie. the public version of
+// this object, without fields relating to the parent journal, linked lists,
+// sequences, etc. These objects are visible to library consumers.
func (e *entry) external() *LogEntry {
return &LogEntry{
DN: e.origin,
@@ -63,9 +69,8 @@
}
}
-// unlink removes this entry from both global and local linked lists, updating the journal's head/tail pointers if
-// needed.
-// journal.mu must be taken as RW
+// unlink removes this entry from both global and local linked lists, updating the
+// journal's head/tail pointers if needed. journal.mu must be taken as RW
func (e *entry) unlink() {
// Unlink from the global linked list.
if e.prevGlobal != nil {
@@ -102,7 +107,8 @@
type quota struct {
// origin is the exact DN that this quota applies to.
origin DN
- // max is the maximum count of log entries permitted for this DN - ie, the maximum size of the local linked list.
+ // max is the maximum count of log entries permitted for this DN - ie, the maximum
+ // size of the local linked list.
max uint64
}
@@ -143,12 +149,13 @@
j.tails[e.origin] = e
}
- // Apply quota to the local linked list that this entry got inserted to, ie. remove elements in excess of the
- // quota.max count.
+ // Apply quota to the local linked list that this entry got inserted to, ie. remove
+ // elements in excess of the quota.max count.
quota := j.quota[e.origin]
count := (j.heads[e.origin].seqLocal - j.tails[e.origin].seqLocal) + 1
if count > quota.max {
- // Keep popping elements off the tail of the local linked list until quota is not violated.
+ // Keep popping elements off the tail of the local linked list until quota is not
+ // violated.
left := count - quota.max
cur := j.tails[e.origin]
for {
diff --git a/metropolis/pkg/logtree/journal_subscriber.go b/metropolis/pkg/logtree/journal_subscriber.go
index e6c7c62..dc9750f 100644
--- a/metropolis/pkg/logtree/journal_subscriber.go
+++ b/metropolis/pkg/logtree/journal_subscriber.go
@@ -24,12 +24,15 @@
type subscriber struct {
// filters that entries need to pass through in order to be sent to the subscriber.
filters []filter
- // dataC is the channel to which entries that pass filters will be sent. The channel must be drained regularly in
- // order to prevent accumulation of goroutines and possible reordering of messages.
+ // dataC is the channel to which entries that pass filters will be sent. The
+ // channel must be drained regularly in order to prevent accumulation of goroutines
+ // and possible reordering of messages.
dataC chan *LogEntry
- // doneC is a channel that is closed once the subscriber wishes to stop receiving notifications.
+ // doneC is a channel that is closed once the subscriber wishes to stop receiving
+ // notifications.
doneC chan struct{}
- // missed is the amount of messages missed by the subscriber by not receiving from dataC fast enough
+ // missed is the amount of messages missed by the subscriber by not receiving from
+ // dataC fast enough
missed uint64
}
diff --git a/metropolis/pkg/logtree/klog.go b/metropolis/pkg/logtree/klog.go
index 8755286..3dd040e 100644
--- a/metropolis/pkg/logtree/klog.go
+++ b/metropolis/pkg/logtree/klog.go
@@ -61,9 +61,8 @@
return k
}
-
type klogParser struct {
- n *node
+ n *node
buffer *logbuffer.LineBuffer
}
@@ -90,7 +89,7 @@
// we permit library users to 'fake' logs? This would also permit us to get rid
// of the type assertion in KLogParser().
e := &entry{
- origin: k.n.dn,
+ origin: k.n.dn,
leveled: p,
}
k.n.tree.journal.append(e)
@@ -98,14 +97,15 @@
}
var (
- // reKLog matches and parses klog/glog-formatted log lines.
- // Format: I0312 14:20:04.240540 204 shared_informer.go:247] Caches are synced for attach detach
+ // reKLog matches and parses klog/glog-formatted log lines. Format: I0312
+ // 14:20:04.240540 204 shared_informer.go:247] Caches are synced for attach
+ // detach
reKLog = regexp.MustCompile(`^([IEWF])(\d{4})\s+(\d{2}:\d{2}:\d{2}(\.\d+)?)\s+(\d+)\s+([^:]+):(\d+)]\s+(.+)$`)
)
// parse attempts to parse a klog-formatted line. Returns nil if the line
// couldn't have been parsed successfully.
-func parse(now time.Time, s string) (*LeveledPayload) {
+func parse(now time.Time, s string) *LeveledPayload {
parts := reKLog.FindStringSubmatch(s)
if parts == nil {
return nil
@@ -184,13 +184,14 @@
// The PID is discarded.
_ = pid
- // Finally we have extracted all the data from the line. Inject into the log publisher.
+ // Finally we have extracted all the data from the line. Inject into the log
+ // publisher.
return &LeveledPayload{
timestamp: ts,
- severity: severity,
- messages: []string{message},
- file: file,
- line: line,
+ severity: severity,
+ messages: []string{message},
+ file: file,
+ line: line,
}
}
diff --git a/metropolis/pkg/logtree/leveled.go b/metropolis/pkg/logtree/leveled.go
index c0d2aff..a4220f9 100644
--- a/metropolis/pkg/logtree/leveled.go
+++ b/metropolis/pkg/logtree/leveled.go
@@ -22,64 +22,70 @@
apb "source.monogon.dev/metropolis/proto/api"
)
-// LeveledLogger is a generic interface for glog-style logging. There are four hardcoded log severities, in increasing
-// order: INFO, WARNING, ERROR, FATAL. Logging at a certain severity level logs not only to consumers expecting data
-// at that severity level, but also all lower severity levels. For example, an ERROR log will also be passed to
-// consumers looking at INFO or WARNING logs.
+// LeveledLogger is a generic interface for glog-style logging. There are four
+// hardcoded log severities, in increasing order: INFO, WARNING, ERROR, FATAL.
+// Logging at a certain severity level logs not only to consumers expecting data at
+// that severity level, but also all lower severity levels. For example, an ERROR
+// log will also be passed to consumers looking at INFO or WARNING logs.
type LeveledLogger interface {
- // Info logs at the INFO severity. Arguments are handled in the manner of fmt.Print, a terminating newline is added
- // if missing.
+ // Info logs at the INFO severity. Arguments are handled in the manner of
+ // fmt.Print, a terminating newline is added if missing.
Info(args ...interface{})
- // Infof logs at the INFO severity. Arguments are handled in the manner of fmt.Printf, a terminating newline is
- // added if missing.
+ // Infof logs at the INFO severity. Arguments are handled in the manner of
+ // fmt.Printf, a terminating newline is added if missing.
Infof(format string, args ...interface{})
- // Warning logs at the WARNING severity. Arguments are handled in the manner of fmt.Print, a terminating newline is
- // added if missing.
+ // Warning logs at the WARNING severity. Arguments are handled in the manner of
+ // fmt.Print, a terminating newline is added if missing.
Warning(args ...interface{})
- // Warningf logs at the WARNING severity. Arguments are handled in the manner of fmt.Printf, a terminating newline
- // is added if missing.
+ // Warningf logs at the WARNING severity. Arguments are handled in the manner of
+ // fmt.Printf, a terminating newline is added if missing.
Warningf(format string, args ...interface{})
- // Error logs at the ERROR severity. Arguments are handled in the manner of fmt.Print, a terminating newline is
- // added if missing.
+ // Error logs at the ERROR severity. Arguments are handled in the manner of
+ // fmt.Print, a terminating newline is added if missing.
Error(args ...interface{})
- // Errorf logs at the ERROR severity. Arguments are handled in the manner of fmt.Printf, a terminating newline is
- // added if missing.
+ // Errorf logs at the ERROR severity. Arguments are handled in the manner of
+ // fmt.Printf, a terminating newline is added if missing.
Errorf(format string, args ...interface{})
- // Fatal logs at the FATAL severity and aborts the current program. Arguments are handled in the manner of
- // fmt.Print, a terminating newline is added if missing.
+ // Fatal logs at the FATAL severity and aborts the current program. Arguments are
+ // handled in the manner of fmt.Print, a terminating newline is added if missing.
Fatal(args ...interface{})
- // Fatalf logs at the FATAL severity and aborts the current program. Arguments are handled in the manner of
- // fmt.Printf, a terminating newline is added if missing.
+ // Fatalf logs at the FATAL severity and aborts the current program. Arguments are
+ // handled in the manner of fmt.Printf, a terminating newline is added if missing.
Fatalf(format string, args ...interface{})
- // V returns a VerboseLeveledLogger at a given verbosity level. These verbosity levels can be dynamically set and
- // unset on a package-granular level by consumers of the LeveledLogger logs. The returned value represents whether
- // logging at the given verbosity level was active at that time, and as such should not be a long-lived object
- // in programs.
- // This construct is further refered to as 'V-logs'.
+ // V returns a VerboseLeveledLogger at a given verbosity level. These verbosity
+ // levels can be dynamically set and unset on a package-granular level by consumers
+ // of the LeveledLogger logs. The returned value represents whether logging at the
+ // given verbosity level was active at that time, and as such should not be a long-
+ // lived object in programs. This construct is further refered to as 'V-logs'.
V(level VerbosityLevel) VerboseLeveledLogger
}
-// VerbosityLevel is a verbosity level defined for V-logs. This can be changed programmatically per Go package. When
-// logging at a given VerbosityLevel V, the current level must be equal or higher to V for the logs to be recorded.
-// Conversely, enabling a V-logging at a VerbosityLevel V also enables all logging at lower levels [Int32Min .. (V-1)].
+// VerbosityLevel is a verbosity level defined for V-logs. This can be changed
+// programmatically per Go package. When logging at a given VerbosityLevel V, the
+// current level must be equal or higher to V for the logs to be recorded.
+// Conversely, enabling a V-logging at a VerbosityLevel V also enables all logging
+// at lower levels [Int32Min .. (V-1)].
type VerbosityLevel int32
type VerboseLeveledLogger interface {
- // Enabled returns if this level was enabled. If not enabled, all logging into this logger will be discarded
- // immediately.
- // Thus, Enabled() can be used to check the verbosity level before performing any logging:
+ // Enabled returns if this level was enabled. If not enabled, all logging into this
+ // logger will be discarded immediately. Thus, Enabled() can be used to check the
+ // verbosity level before performing any logging:
// if l.V(3).Enabled() { l.Info("V3 is enabled") }
// or, in simple cases, the convenience function .Info can be used:
// l.V(3).Info("V3 is enabled")
- // The second form is shorter and more convenient, but more expensive, as its arguments are always evaluated.
+ // The second form is shorter and more convenient, but more expensive, as its
+ // arguments are always evaluated.
Enabled() bool
- // Info is the equivalent of a LeveledLogger's Info call, guarded by whether this VerboseLeveledLogger is enabled.
+ // Info is the equivalent of a LeveledLogger's Info call, guarded by whether this
+ // VerboseLeveledLogger is enabled.
Info(args ...interface{})
- // Infof is the equivalent of a LeveledLogger's Infof call, guarded by whether this VerboseLeveledLogger is enabled.
+ // Infof is the equivalent of a LeveledLogger's Infof call, guarded by whether this
+ // VerboseLeveledLogger is enabled.
Infof(format string, args ...interface{})
}
@@ -94,8 +100,9 @@
)
var (
- // SeverityAtLeast maps a given severity to a list of severities that at that severity or higher. In other words,
- // SeverityAtLeast[X] returns a list of severities that might be seen in a log at severity X.
+ // SeverityAtLeast maps a given severity to a list of severities that at that
+ // severity or higher. In other words, SeverityAtLeast[X] returns a list of
+ // severities that might be seen in a log at severity X.
SeverityAtLeast = map[Severity][]Severity{
INFO: {INFO, WARNING, ERROR, FATAL},
WARNING: {WARNING, ERROR, FATAL},
diff --git a/metropolis/pkg/logtree/leveled_payload.go b/metropolis/pkg/logtree/leveled_payload.go
index 0ceee4d..ed3ed7e 100644
--- a/metropolis/pkg/logtree/leveled_payload.go
+++ b/metropolis/pkg/logtree/leveled_payload.go
@@ -25,12 +25,13 @@
apb "source.monogon.dev/metropolis/proto/api"
)
-// LeveledPayload is a log entry for leveled logs (as per leveled.go). It contains the input to these calls (severity and
-// message split into newline-delimited messages) and additional metadata that would be usually seen in a text
+// LeveledPayload is a log entry for leveled logs (as per leveled.go). It contains
+// the input to these calls (severity and message split into newline-delimited
+// messages) and additional metadata that would be usually seen in a text
// representation of a leveled log entry.
type LeveledPayload struct {
- // messages is the list of messages contained in this payload. This list is built from splitting up the given message
- // from the user by newline.
+ // messages is the list of messages contained in this payload. This list is built
+ // from splitting up the given message from the user by newline.
messages []string
// timestamp is the time at which this message was emitted.
timestamp time.Time
@@ -42,10 +43,11 @@
line int
}
-// String returns a canonical representation of this payload as a single string prefixed with metadata. If the original
-// message was logged with newlines, this representation will also contain newlines, with each original message part
-// prefixed by the metadata.
-// For an alternative call that will instead return a canonical prefix and a list of lines in the message, see Strings().
+// String returns a canonical representation of this payload as a single string
+// prefixed with metadata. If the original message was logged with newlines, this
+// representation will also contain newlines, with each original message part
+// prefixed by the metadata. For an alternative call that will instead return a
+// canonical prefix and a list of lines in the message, see Strings().
func (p *LeveledPayload) String() string {
prefix, lines := p.Strings()
res := make([]string, len(p.messages))
@@ -55,9 +57,11 @@
return strings.Join(res, "\n")
}
-// Strings returns the canonical representation of this payload split into a prefix and all lines that were contained in
-// the original message. This is meant to be displayed to the user by showing the prefix before each line, concatenated
-// together - possibly in a table form with the prefixes all unified with a rowspan-like mechanism.
+// Strings returns the canonical representation of this payload split into a
+// prefix and all lines that were contained in the original message. This is
+// meant to be displayed to the user by showing the prefix before each line,
+// concatenated together - possibly in a table form with the prefixes all
+// unified with a rowspan- like mechanism.
//
// For example, this function can return:
// prefix = "I1102 17:20:06.921395 foo.go:42] "
@@ -76,7 +80,6 @@
// | :------------------|
// | : - two |
// '-----------------------------------------------------------'
-//
func (p *LeveledPayload) Strings() (prefix string, lines []string) {
_, month, day := p.timestamp.Date()
hour, minute, second := p.timestamp.Clock()
@@ -91,8 +94,8 @@
return
}
-// Message returns the inner message lines of this entry, ie. what was passed to the actual logging method, but split by
-// newlines.
+// Message returns the inner message lines of this entry, ie. what was passed to
+// the actual logging method, but split by newlines.
func (p *LeveledPayload) Messages() []string { return p.messages }
func (p *LeveledPayload) MessagesJoined() string { return strings.Join(p.messages, "\n") }
@@ -100,8 +103,8 @@
// Timestamp returns the time at which this entry was logged.
func (p *LeveledPayload) Timestamp() time.Time { return p.timestamp }
-// Location returns a string in the form of file_name:line_number that shows the origin of the log entry in the
-// program source.
+// Location returns a string in the form of file_name:line_number that shows the
+// origin of the log entry in the program source.
func (p *LeveledPayload) Location() string { return fmt.Sprintf("%s:%d", p.file, p.line) }
// Severity returns the Severity with which this entry was logged.
diff --git a/metropolis/pkg/logtree/logtree.go b/metropolis/pkg/logtree/logtree.go
index a21545f..968a5a9 100644
--- a/metropolis/pkg/logtree/logtree.go
+++ b/metropolis/pkg/logtree/logtree.go
@@ -24,12 +24,13 @@
"source.monogon.dev/metropolis/pkg/logbuffer"
)
-// LogTree is a tree-shaped logging system. For more information, see the package-level documentation.
+// LogTree is a tree-shaped logging system. For more information, see the package-
+// level documentation.
type LogTree struct {
// journal is the tree's journal, storing all log data and managing subscribers.
journal *journal
- // root is the root node of the actual tree of the log tree. The nodes contain per-DN configuration options, notably
- // the current verbosity level of that DN.
+ // root is the root node of the actual tree of the log tree. The nodes contain per-
+ // DN configuration options, notably the current verbosity level of that DN.
root *node
}
@@ -41,25 +42,29 @@
return lt
}
-// node represents a given DN as a discrete 'logger'. It implements the LeveledLogger interface for log publishing,
-// entries from which it passes over to the logtree's journal.
+// node represents a given DN as a discrete 'logger'. It implements the
+// LeveledLogger interface for log publishing, entries from which it passes over to
+// the logtree's journal.
type node struct {
// dn is the DN which this node represents (or "" if this is the root node).
dn DN
// tree is the LogTree to which this node belongs.
tree *LogTree
- // verbosity is the current verbosity level of this DN/node, affecting .V(n) LeveledLogger calls
+ // verbosity is the current verbosity level of this DN/node, affecting .V(n)
+ // LeveledLogger calls
verbosity VerbosityLevel
rawLineBuffer *logbuffer.LineBuffer
// mu guards children.
mu sync.Mutex
- // children is a map of DN-part to a children node in the logtree. A DN-part is a string representing a part of the
- // DN between the deliming dots, as returned by DN.Path.
+ // children is a map of DN-part to a children node in the logtree. A DN-part is a
+ // string representing a part of the DN between the deliming dots, as returned by
+ // DN.Path.
children map[string]*node
}
-// newNode returns a node at a given DN in the LogTree - but doesn't set up the LogTree to insert it accordingly.
+// newNode returns a node at a given DN in the LogTree - but doesn't set up the
+// LogTree to insert it accordingly.
func newNode(tree *LogTree, dn DN) *node {
n := &node{
dn: dn,
@@ -72,8 +77,8 @@
return n
}
-// nodeByDN returns the LogTree node corresponding to a given DN. If either the node or some of its parents do not
-// exist they will be created as needed.
+// nodeByDN returns the LogTree node corresponding to a given DN. If either the
+// node or some of its parents do not exist they will be created as needed.
func (l *LogTree) nodeByDN(dn DN) (*node, error) {
traversal, err := newTraversal(dn)
if err != nil {
@@ -82,22 +87,27 @@
return traversal.execute(l.root), nil
}
-// nodeTraversal represents a request to traverse the LogTree in search of a given node by DN.
+// nodeTraversal represents a request to traverse the LogTree in search of a given
+// node by DN.
type nodeTraversal struct {
// want is the DN of the node's that requested to be found.
want DN
- // current is the path already taken to find the node, in the form of DN parts. It starts out as want.Parts() and
- // progresses to become empty as the traversal continues.
+ // current is the path already taken to find the node, in the form of DN parts. It
+ // starts out as want.Parts() and progresses to become empty as the traversal
+ // continues.
current []string
- // left is the path that's still needed to be taken in order to find the node, in the form of DN parts. It starts
- // out empty and progresses to become wants.Parts() as the traversal continues.
+ // left is the path that's still needed to be taken in order to find the node, in
+ // the form of DN parts. It starts out empty and progresses to become wants.Parts()
+ // as the traversal continues.
left []string
}
-// next adjusts the traversal's current/left slices to the next element of the traversal, returns the part that's now
-// being looked for (or "" if the traveral is done) and the full DN of the element that's being looked for.
+// next adjusts the traversal's current/left slices to the next element of the
+// traversal, returns the part that's now being looked for (or "" if the traveral
+// is done) and the full DN of the element that's being looked for.
//
-// For example, a traversal of foo.bar.baz will cause .next() to return the following on each invocation:
+// For example, a traversal of foo.bar.baz will cause .next() to return the
+// following on each invocation:
// - part: foo, full: foo
// - part: bar, full: foo.bar
// - part: baz, full: foo.bar.baz
@@ -125,9 +135,10 @@
}, nil
}
-// execute the traversal in order to find the node. This can only be called once per traversal.
-// Nodes will be created within the tree until the target node is reached. Existing nodes will be reused.
-// This is effectively an idempotent way of accessing a node in the tree based on a traversal.
+// execute the traversal in order to find the node. This can only be called once
+// per traversal. Nodes will be created within the tree until the target node is
+// reached. Existing nodes will be reused. This is effectively an idempotent way of
+// accessing a node in the tree based on a traversal.
func (t *nodeTraversal) execute(n *node) *node {
cur := n
for {
diff --git a/metropolis/pkg/logtree/logtree_access.go b/metropolis/pkg/logtree/logtree_access.go
index fed202e..1babe1e 100644
--- a/metropolis/pkg/logtree/logtree_access.go
+++ b/metropolis/pkg/logtree/logtree_access.go
@@ -31,46 +31,54 @@
leveledWithMinimumSeverity Severity
}
-// WithChildren makes Read return/stream data for both a given DN and all its children.
+// WithChildren makes Read return/stream data for both a given DN and all its
+// children.
func WithChildren() LogReadOption { return LogReadOption{withChildren: true} }
-// WithStream makes Read return a stream of data. This works alongside WithBacklog to create a read-and-stream
-// construct.
+// WithStream makes Read return a stream of data. This works alongside WithBacklog
+// to create a read-and-stream construct.
func WithStream() LogReadOption { return LogReadOption{withStream: true} }
-// WithBacklog makes Read return already recorded log entries, up to count elements.
+// WithBacklog makes Read return already recorded log entries, up to count
+// elements.
func WithBacklog(count int) LogReadOption { return LogReadOption{withBacklog: count} }
-// BacklogAllAvailable makes WithBacklog return all backlogged log data that logtree possesses.
+// BacklogAllAvailable makes WithBacklog return all backlogged log data that
+// logtree possesses.
const BacklogAllAvailable int = -1
func OnlyRaw() LogReadOption { return LogReadOption{onlyRaw: true} }
func OnlyLeveled() LogReadOption { return LogReadOption{onlyLeveled: true} }
-// LeveledWithMinimumSeverity makes Read return only log entries that are at least at a given Severity. If only leveled
-// entries are needed, OnlyLeveled must be used. This is a no-op when OnlyRaw is used.
+// LeveledWithMinimumSeverity makes Read return only log entries that are at least
+// at a given Severity. If only leveled entries are needed, OnlyLeveled must be
+// used. This is a no-op when OnlyRaw is used.
func LeveledWithMinimumSeverity(s Severity) LogReadOption {
return LogReadOption{leveledWithMinimumSeverity: s}
}
-// LogReader permits reading an already existing backlog of log entries and to stream further ones.
+// LogReader permits reading an already existing backlog of log entries and to
+// stream further ones.
type LogReader struct {
- // Backlog are the log entries already logged by LogTree. This will only be set if WithBacklog has been passed to
- // Read.
+ // Backlog are the log entries already logged by LogTree. This will only be set if
+ // WithBacklog has been passed to Read.
Backlog []*LogEntry
- // Stream is a channel of new entries as received live by LogTree. This will only be set if WithStream has been
- // passed to Read. In this case, entries from this channel must be read as fast as possible by the consumer in order
- // to prevent missing entries.
+ // Stream is a channel of new entries as received live by LogTree. This will only
+ // be set if WithStream has been passed to Read. In this case, entries from this
+ // channel must be read as fast as possible by the consumer in order to prevent
+ // missing entries.
Stream <-chan *LogEntry
- // done is channel used to signal (by closing) that the log consumer is not interested in more Stream data.
+ // done is channel used to signal (by closing) that the log consumer is not
+ // interested in more Stream data.
done chan<- struct{}
- // missed is an atomic integer pointer that tells the subscriber how many messages in Stream they missed. This
- // pointer is nil if no streaming has been requested.
+ // missed is an atomic integer pointer that tells the subscriber how many messages
+ // in Stream they missed. This pointer is nil if no streaming has been requested.
missed *uint64
}
-// Missed returns the amount of entries that were missed from Stream (as the channel was not drained fast enough).
+// Missed returns the amount of entries that were missed from Stream (as the
+// channel was not drained fast enough).
func (l *LogReader) Missed() uint64 {
// No Stream.
if l.missed == nil {
@@ -79,8 +87,8 @@
return atomic.LoadUint64(l.missed)
}
-// Close closes the LogReader's Stream. This must be called once the Reader does not wish to receive streaming messages
-// anymore.
+// Close closes the LogReader's Stream. This must be called once the Reader does
+// not wish to receive streaming messages anymore.
func (l *LogReader) Close() {
if l.done != nil {
close(l.done)
@@ -91,9 +99,11 @@
ErrRawAndLeveled = errors.New("cannot return logs that are simultaneously OnlyRaw and OnlyLeveled")
)
-// Read and/or stream entries from a LogTree. The returned LogReader is influenced by the LogReadOptions passed, which
-// influence whether the Read will return existing entries, a stream, or both. In addition the options also dictate
-// whether only entries for that particular DN are returned, or for all sub-DNs as well.
+// Read and/or stream entries from a LogTree. The returned LogReader is influenced
+// by the LogReadOptions passed, which influence whether the Read will return
+// existing entries, a stream, or both. In addition the options also dictate
+// whether only entries for that particular DN are returned, or for all sub-DNs as
+// well.
func (l *LogTree) Read(dn DN, opts ...LogReadOption) (*LogReader, error) {
l.journal.mu.RLock()
defer l.journal.mu.RUnlock()
diff --git a/metropolis/pkg/logtree/logtree_entry.go b/metropolis/pkg/logtree/logtree_entry.go
index a1c2d62..442d456 100644
--- a/metropolis/pkg/logtree/logtree_entry.go
+++ b/metropolis/pkg/logtree/logtree_entry.go
@@ -24,8 +24,9 @@
apb "source.monogon.dev/metropolis/proto/api"
)
-// LogEntry contains a log entry, combining both leveled and raw logging into a single stream of events. A LogEntry
-// will contain exactly one of either LeveledPayload or RawPayload.
+// LogEntry contains a log entry, combining both leveled and raw logging into a
+// single stream of events. A LogEntry will contain exactly one of either
+// LeveledPayload or RawPayload.
type LogEntry struct {
// If non-nil, this is a leveled logging entry.
Leveled *LeveledPayload
@@ -35,10 +36,12 @@
DN DN
}
-// String returns a canonical representation of this payload as a single string prefixed with metadata. If the entry is
-// a leveled log entry that originally was logged with newlines this representation will also contain newlines, with
-// each original message part prefixed by the metadata.
-// For an alternative call that will instead return a canonical prefix and a list of lines in the message, see Strings().
+// String returns a canonical representation of this payload as a single string
+// prefixed with metadata. If the entry is a leveled log entry that originally was
+// logged with newlines this representation will also contain newlines, with each
+// original message part prefixed by the metadata. For an alternative call that
+// will instead return a canonical prefix and a list of lines in the message, see
+// Strings().
func (l *LogEntry) String() string {
if l.Leveled != nil {
prefix, messages := l.Leveled.Strings()
@@ -54,9 +57,11 @@
return "INVALID"
}
-// Strings returns the canonical representation of this payload split into a prefix and all lines that were contained in
-// the original message. This is meant to be displayed to the user by showing the prefix before each line, concatenated
-// together - possibly in a table form with the prefixes all unified with a rowspan-like mechanism.
+// Strings returns the canonical representation of this payload split into a
+// prefix and all lines that were contained in the original message. This is
+// meant to be displayed to the user by showing the prefix before each line,
+// concatenated together - possibly in a table form with the prefixes all
+// unified with a rowspan- like mechanism.
//
// For example, this function can return:
// prefix = "root.foo.bar I1102 17:20:06.921395 0 foo.go:42] "
@@ -68,14 +73,14 @@
// root.foo.bar I1102 17:20:06.921395 foo.go:42] - two
//
// Or, in a table layout:
-// .-------------------------------------------------------------------------------------.
-// | root.foo.bar I1102 17:20:06.921395 foo.go:42] : current tags: |
-// | :------------------|
-// | : - one |
-// | :------------------|
-// | : - two |
-// '-------------------------------------------------------------------------------------'
-//
+// .----------------------------------------------------------------------.
+// | root.foo.bar I1102 17:20:06.921395 foo.go:42] : current tags: |
+// | :------------------|
+// | : - one |
+// | :------------------|
+// | : - two |
+// '----------------------------------------------------------------------'
+
func (l *LogEntry) Strings() (prefix string, lines []string) {
if l.Leveled != nil {
prefix, messages := l.Leveled.Strings()
@@ -88,8 +93,8 @@
return "INVALID ", []string{"INVALID"}
}
-// Convert this LogEntry to proto. Returned value may be nil if given LogEntry is invalid, eg. contains neither a Raw
-// nor Leveled entry.
+// Convert this LogEntry to proto. Returned value may be nil if given LogEntry is
+// invalid, eg. contains neither a Raw nor Leveled entry.
func (l *LogEntry) Proto() *apb.LogEntry {
p := &apb.LogEntry{
Dn: string(l.DN),
@@ -111,8 +116,8 @@
return p
}
-// Parse a proto LogEntry back into internal structure. This can be used in log proto API consumers to easily print
-// received log entries.
+// Parse a proto LogEntry back into internal structure. This can be used in log
+// proto API consumers to easily print received log entries.
func LogEntryFromProto(l *apb.LogEntry) (*LogEntry, error) {
dn := DN(l.Dn)
if _, err := dn.Path(); err != nil {
diff --git a/metropolis/pkg/logtree/logtree_publisher.go b/metropolis/pkg/logtree/logtree_publisher.go
index d4d35ff..6106b19 100644
--- a/metropolis/pkg/logtree/logtree_publisher.go
+++ b/metropolis/pkg/logtree/logtree_publisher.go
@@ -26,8 +26,8 @@
"source.monogon.dev/metropolis/pkg/logbuffer"
)
-// LeveledFor returns a LeveledLogger publishing interface for a given DN. An error may be returned if the DN is
-// malformed.
+// LeveledFor returns a LeveledLogger publishing interface for a given DN. An error
+// may be returned if the DN is malformed.
func (l *LogTree) LeveledFor(dn DN) (LeveledLogger, error) {
return l.nodeByDN(dn)
}
@@ -40,7 +40,8 @@
return node.rawLineBuffer, nil
}
-// MustLeveledFor returns a LeveledLogger publishing interface for a given DN, or panics if the given DN is invalid.
+// MustLeveledFor returns a LeveledLogger publishing interface for a given DN, or
+// panics if the given DN is invalid.
func (l *LogTree) MustLeveledFor(dn DN) LeveledLogger {
leveled, err := l.LeveledFor(dn)
if err != nil {
@@ -57,7 +58,8 @@
return raw
}
-// SetVerbosity sets the verbosity for a given DN (non-recursively, ie. for that DN only, not its children).
+// SetVerbosity sets the verbosity for a given DN (non-recursively, ie. for that DN
+// only, not its children).
func (l *LogTree) SetVerbosity(dn DN, level VerbosityLevel) error {
node, err := l.nodeByDN(dn)
if err != nil {
@@ -67,8 +69,9 @@
return nil
}
-// logRaw is called by this node's LineBuffer any time a raw log line is completed. It will create a new entry, append
-// it to the journal, and notify all pertinent subscribers.
+// logRaw is called by this node's LineBuffer any time a raw log line is completed.
+// It will create a new entry, append it to the journal, and notify all pertinent
+// subscribers.
func (n *node) logRaw(line *logbuffer.Line) {
e := &entry{
origin: n.dn,
@@ -78,8 +81,9 @@
n.tree.journal.notify(e)
}
-// log builds a LeveledPayload and entry for a given message, including all related metadata. It will create a new
-// entry append it to the journal, and notify all pertinent subscribers.
+// log builds a LeveledPayload and entry for a given message, including all related
+// metadata. It will create a new entry append it to the journal, and notify all
+// pertinent subscribers.
func (n *node) logLeveled(depth int, severity Severity, msg string) {
_, file, line, ok := runtime.Caller(2 + depth)
if !ok {
@@ -158,9 +162,10 @@
}
}
-// verbose implements the VerboseLeveledLogger interface. It is a thin wrapper around node, with an 'enabled' bool. This
-// means that V(n)-returned VerboseLeveledLoggers must be short lived, as a changed in verbosity will not affect all
-// already existing VerboseLeveledLoggers.
+// verbose implements the VerboseLeveledLogger interface. It is a thin wrapper
+// around node, with an 'enabled' bool. This means that V(n)-returned
+// VerboseLeveledLoggers must be short lived, as a changed in verbosity will not
+// affect all already existing VerboseLeveledLoggers.
type verbose struct {
node *node
enabled bool