metropolis/proto: move log-related types to common
Having them in API is kinda weird, especially as we're
generating/parsing them from a few libraries already.
Change-Id: I87b4b51f151443c60b87e3e50753c395fcf6e845
Reviewed-on: https://review.monogon.dev/c/monogon/+/1437
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/cli/dbg/BUILD.bazel b/metropolis/cli/dbg/BUILD.bazel
index 4eed080..5991f63 100644
--- a/metropolis/cli/dbg/BUILD.bazel
+++ b/metropolis/cli/dbg/BUILD.bazel
@@ -8,6 +8,7 @@
deps = [
"//metropolis/pkg/logtree",
"//metropolis/proto/api",
+ "//metropolis/proto/common",
"@io_k8s_cli_runtime//pkg/genericclioptions",
"@io_k8s_component_base//cli",
"@io_k8s_kubectl//pkg/cmd",
diff --git a/metropolis/cli/dbg/main.go b/metropolis/cli/dbg/main.go
index 0af835a..f7eb1a4 100644
--- a/metropolis/cli/dbg/main.go
+++ b/metropolis/cli/dbg/main.go
@@ -34,7 +34,9 @@
"k8s.io/kubectl/pkg/cmd/util"
"source.monogon.dev/metropolis/pkg/logtree"
+
apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
func main() {
@@ -110,8 +112,8 @@
}
if *logsRecursive {
- req.Filters = append(req.Filters, &apb.LogFilter{
- Filter: &apb.LogFilter_WithChildren_{WithChildren: &apb.LogFilter_WithChildren{}},
+ req.Filters = append(req.Filters, &cpb.LogFilter{
+ Filter: &cpb.LogFilter_WithChildren_{WithChildren: &cpb.LogFilter_WithChildren{}},
})
}
@@ -137,6 +139,14 @@
}
fmt.Println(entry.String())
}
+ for _, entry := range res.StreamEntries {
+ entry, err := logtree.LogEntryFromProto(entry)
+ if err != nil {
+ fmt.Printf("error decoding entry: %v", err)
+ continue
+ }
+ fmt.Println(entry.String())
+ }
}
case "kubectl":
// Pop "kubectl" arg (the k8s cli library internally parses os.Args).
diff --git a/metropolis/cli/metroctl/BUILD.bazel b/metropolis/cli/metroctl/BUILD.bazel
index 73a0a6e..71258e9 100644
--- a/metropolis/cli/metroctl/BUILD.bazel
+++ b/metropolis/cli/metroctl/BUILD.bazel
@@ -32,6 +32,7 @@
"//metropolis/node/core/rpc",
"//metropolis/pkg/logtree",
"//metropolis/proto/api",
+ "//metropolis/proto/common",
"@com_github_adrg_xdg//:xdg",
"@com_github_spf13_cobra//:cobra",
"@io_k8s_apimachinery//pkg/apis/meta/v1:meta",
diff --git a/metropolis/cli/metroctl/cmd_node_logs.go b/metropolis/cli/metroctl/cmd_node_logs.go
index 21d5637..beae6ab 100644
--- a/metropolis/cli/metroctl/cmd_node_logs.go
+++ b/metropolis/cli/metroctl/cmd_node_logs.go
@@ -11,6 +11,7 @@
"source.monogon.dev/metropolis/cli/metroctl/core"
"source.monogon.dev/metropolis/pkg/logtree"
"source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
var nodeLogsCmd = &cobra.Command{
@@ -59,10 +60,10 @@
Dn: "",
BacklogMode: api.GetLogsRequest_BACKLOG_ALL,
StreamMode: api.GetLogsRequest_STREAM_DISABLE,
- Filters: []*api.LogFilter{
+ Filters: []*cpb.LogFilter{
{
- Filter: &api.LogFilter_WithChildren_{
- WithChildren: &api.LogFilter_WithChildren{},
+ Filter: &cpb.LogFilter_WithChildren_{
+ WithChildren: &cpb.LogFilter_WithChildren{},
},
},
},
diff --git a/metropolis/node/core/BUILD.bazel b/metropolis/node/core/BUILD.bazel
index 37897e5..281266b 100644
--- a/metropolis/node/core/BUILD.bazel
+++ b/metropolis/node/core/BUILD.bazel
@@ -35,6 +35,7 @@
"//metropolis/pkg/supervisor",
"//metropolis/pkg/tpm",
"//metropolis/proto/api",
+ "//metropolis/proto/common",
"@com_github_containerd_containerd//:containerd",
"@com_github_containerd_containerd//namespaces",
"@org_golang_google_grpc//:go_default_library",
diff --git a/metropolis/node/core/debug_service_enabled.go b/metropolis/node/core/debug_service_enabled.go
index fc77edb..3494270 100644
--- a/metropolis/node/core/debug_service_enabled.go
+++ b/metropolis/node/core/debug_service_enabled.go
@@ -37,6 +37,7 @@
"source.monogon.dev/metropolis/pkg/logtree"
"source.monogon.dev/metropolis/pkg/supervisor"
apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
const (
@@ -139,13 +140,13 @@
// Parse proto filters into logtree options.
for i, filter := range req.Filters {
switch inner := filter.Filter.(type) {
- case *apb.LogFilter_WithChildren_:
+ case *cpb.LogFilter_WithChildren_:
options = append(options, logtree.WithChildren())
- case *apb.LogFilter_OnlyRaw_:
+ case *cpb.LogFilter_OnlyRaw_:
options = append(options, logtree.OnlyRaw())
- case *apb.LogFilter_OnlyLeveled_:
+ case *cpb.LogFilter_OnlyLeveled_:
options = append(options, logtree.OnlyLeveled())
- case *apb.LogFilter_LeveledWithMinimumSeverity_:
+ case *cpb.LogFilter_LeveledWithMinimumSeverity_:
severity, err := logtree.SeverityFromProto(inner.LeveledWithMinimumSeverity.Minimum)
if err != nil {
return status.Errorf(codes.InvalidArgument, "filter %d has invalid severity: %v", i, err)
@@ -179,7 +180,7 @@
maxChunkSize := 2000
// Serve all backlog entries in chunks.
- chunk := make([]*apb.LogEntry, 0, maxChunkSize)
+ chunk := make([]*cpb.LogEntry, 0, maxChunkSize)
for _, entry := range reader.Backlog {
p := entry.Proto()
if p == nil {
@@ -195,7 +196,7 @@
if err != nil {
return err
}
- chunk = make([]*apb.LogEntry, 0, maxChunkSize)
+ chunk = make([]*cpb.LogEntry, 0, maxChunkSize)
}
}
@@ -207,7 +208,7 @@
if err != nil {
return err
}
- chunk = make([]*apb.LogEntry, 0, maxChunkSize)
+ chunk = make([]*cpb.LogEntry, 0, maxChunkSize)
}
// Start serving streaming data, if streaming has been requested.
@@ -227,7 +228,7 @@
continue
}
err := srv.Send(&apb.GetLogsResponse{
- StreamEntries: []*apb.LogEntry{p},
+ StreamEntries: []*cpb.LogEntry{p},
})
if err != nil {
return err
diff --git a/metropolis/pkg/logbuffer/BUILD.bazel b/metropolis/pkg/logbuffer/BUILD.bazel
index cd0e3af..e890df8 100644
--- a/metropolis/pkg/logbuffer/BUILD.bazel
+++ b/metropolis/pkg/logbuffer/BUILD.bazel
@@ -8,7 +8,7 @@
],
importpath = "source.monogon.dev/metropolis/pkg/logbuffer",
visibility = ["//metropolis:__subpackages__"],
- deps = ["//metropolis/proto/api"],
+ deps = ["//metropolis/proto/common"],
)
go_test(
diff --git a/metropolis/pkg/logbuffer/linebuffer.go b/metropolis/pkg/logbuffer/linebuffer.go
index 6fd9a62..16f7b1a 100644
--- a/metropolis/pkg/logbuffer/linebuffer.go
+++ b/metropolis/pkg/logbuffer/linebuffer.go
@@ -22,7 +22,7 @@
"strings"
"sync"
- apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
// Line is a line stored in the log buffer - a string, that has been perhaps
@@ -47,15 +47,15 @@
}
// ProtoLog returns a Logging-specific protobuf structure.
-func (l *Line) ProtoLog() *apb.LogEntry_Raw {
- return &apb.LogEntry_Raw{
+func (l *Line) ProtoLog() *cpb.LogEntry_Raw {
+ return &cpb.LogEntry_Raw{
Data: l.Data,
OriginalLength: int64(l.OriginalLength),
}
}
// LineFromLogProto converts a Logging-specific protobuf message back into a Line.
-func LineFromLogProto(raw *apb.LogEntry_Raw) (*Line, error) {
+func LineFromLogProto(raw *cpb.LogEntry_Raw) (*Line, error) {
if raw.OriginalLength < int64(len(raw.Data)) {
return nil, fmt.Errorf("original_length smaller than length of data")
}
diff --git a/metropolis/pkg/logtree/BUILD.bazel b/metropolis/pkg/logtree/BUILD.bazel
index 5c4237c..2e2f07e 100644
--- a/metropolis/pkg/logtree/BUILD.bazel
+++ b/metropolis/pkg/logtree/BUILD.bazel
@@ -20,7 +20,7 @@
visibility = ["//metropolis:__subpackages__"],
deps = [
"//metropolis/pkg/logbuffer",
- "//metropolis/proto/api",
+ "//metropolis/proto/common",
"@com_github_mitchellh_go_wordwrap//:go-wordwrap",
"@org_golang_google_protobuf//types/known/timestamppb",
],
diff --git a/metropolis/pkg/logtree/leveled.go b/metropolis/pkg/logtree/leveled.go
index 6e44ef4..5c57222 100644
--- a/metropolis/pkg/logtree/leveled.go
+++ b/metropolis/pkg/logtree/leveled.go
@@ -19,7 +19,7 @@
import (
"fmt"
- apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
// LeveledLogger is a generic interface for glog-style logging. There are four
@@ -144,32 +144,32 @@
}
}
-func SeverityFromProto(s apb.LeveledLogSeverity) (Severity, error) {
+func SeverityFromProto(s cpb.LeveledLogSeverity) (Severity, error) {
switch s {
- case apb.LeveledLogSeverity_INFO:
+ case cpb.LeveledLogSeverity_INFO:
return INFO, nil
- case apb.LeveledLogSeverity_WARNING:
+ case cpb.LeveledLogSeverity_WARNING:
return WARNING, nil
- case apb.LeveledLogSeverity_ERROR:
+ case cpb.LeveledLogSeverity_ERROR:
return ERROR, nil
- case apb.LeveledLogSeverity_FATAL:
+ case cpb.LeveledLogSeverity_FATAL:
return FATAL, nil
default:
return "", fmt.Errorf("unknown severity value %d", s)
}
}
-func (s Severity) ToProto() apb.LeveledLogSeverity {
+func (s Severity) ToProto() cpb.LeveledLogSeverity {
switch s {
case INFO:
- return apb.LeveledLogSeverity_INFO
+ return cpb.LeveledLogSeverity_INFO
case WARNING:
- return apb.LeveledLogSeverity_WARNING
+ return cpb.LeveledLogSeverity_WARNING
case ERROR:
- return apb.LeveledLogSeverity_ERROR
+ return cpb.LeveledLogSeverity_ERROR
case FATAL:
- return apb.LeveledLogSeverity_FATAL
+ return cpb.LeveledLogSeverity_FATAL
default:
- return apb.LeveledLogSeverity_INVALID
+ return cpb.LeveledLogSeverity_INVALID
}
}
diff --git a/metropolis/pkg/logtree/leveled_payload.go b/metropolis/pkg/logtree/leveled_payload.go
index 909d88a..c0852ae 100644
--- a/metropolis/pkg/logtree/leveled_payload.go
+++ b/metropolis/pkg/logtree/leveled_payload.go
@@ -24,7 +24,7 @@
tpb "google.golang.org/protobuf/types/known/timestamppb"
- apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
// LeveledPayload is a log entry for leveled logs (as per leveled.go). It contains
@@ -66,8 +66,9 @@
// unified with a rowspan- like mechanism.
//
// For example, this function can return:
-// prefix = "I1102 17:20:06.921395 foo.go:42] "
-// lines = []string{"current tags:", " - one", " - two"}
+//
+// prefix = "I1102 17:20:06.921395 foo.go:42] "
+// lines = []string{"current tags:", " - one", " - two"}
//
// With this data, the result should be presented to users this way in text form:
// I1102 17:20:06.921395 foo.go:42] current tags:
@@ -113,8 +114,8 @@
func (p *LeveledPayload) Severity() Severity { return p.severity }
// Proto converts a LeveledPayload to protobuf format.
-func (p *LeveledPayload) Proto() *apb.LogEntry_Leveled {
- return &apb.LogEntry_Leveled{
+func (p *LeveledPayload) Proto() *cpb.LogEntry_Leveled {
+ return &cpb.LogEntry_Leveled{
Lines: p.Messages(),
Timestamp: tpb.New(p.Timestamp()),
Severity: p.Severity().ToProto(),
@@ -123,7 +124,7 @@
}
// LeveledPayloadFromProto parses a protobuf message into the internal format.
-func LeveledPayloadFromProto(p *apb.LogEntry_Leveled) (*LeveledPayload, error) {
+func LeveledPayloadFromProto(p *cpb.LogEntry_Leveled) (*LeveledPayload, error) {
severity, err := SeverityFromProto(p.Severity)
if err != nil {
return nil, fmt.Errorf("could not convert severity: %w", err)
diff --git a/metropolis/pkg/logtree/logtree_entry.go b/metropolis/pkg/logtree/logtree_entry.go
index a020910..72cc409 100644
--- a/metropolis/pkg/logtree/logtree_entry.go
+++ b/metropolis/pkg/logtree/logtree_entry.go
@@ -23,7 +23,7 @@
"github.com/mitchellh/go-wordwrap"
"source.monogon.dev/metropolis/pkg/logbuffer"
- apb "source.monogon.dev/metropolis/proto/api"
+ cpb "source.monogon.dev/metropolis/proto/common"
)
// LogEntry contains a log entry, combining both leveled and raw logging into a
@@ -207,19 +207,19 @@
// 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{
+func (l *LogEntry) Proto() *cpb.LogEntry {
+ p := &cpb.LogEntry{
Dn: string(l.DN),
}
switch {
case l.Leveled != nil:
leveled := l.Leveled
- p.Kind = &apb.LogEntry_Leveled_{
+ p.Kind = &cpb.LogEntry_Leveled_{
Leveled: leveled.Proto(),
}
case l.Raw != nil:
raw := l.Raw
- p.Kind = &apb.LogEntry_Raw_{
+ p.Kind = &cpb.LogEntry_Raw_{
Raw: raw.ProtoLog(),
}
default:
@@ -230,7 +230,7 @@
// 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) {
+func LogEntryFromProto(l *cpb.LogEntry) (*LogEntry, error) {
dn := DN(l.Dn)
if _, err := dn.Path(); err != nil {
return nil, fmt.Errorf("could not convert DN: %w", err)
@@ -239,13 +239,13 @@
DN: dn,
}
switch inner := l.Kind.(type) {
- case *apb.LogEntry_Leveled_:
+ case *cpb.LogEntry_Leveled_:
leveled, err := LeveledPayloadFromProto(inner.Leveled)
if err != nil {
return nil, fmt.Errorf("could not convert leveled entry: %w", err)
}
res.Leveled = leveled
- case *apb.LogEntry_Raw_:
+ case *cpb.LogEntry_Raw_:
line, err := logbuffer.LineFromLogProto(inner.Raw)
if err != nil {
return nil, fmt.Errorf("could not convert raw entry: %w", err)
diff --git a/metropolis/proto/api/debug.proto b/metropolis/proto/api/debug.proto
index 156f036..b70d1a0 100644
--- a/metropolis/proto/api/debug.proto
+++ b/metropolis/proto/api/debug.proto
@@ -28,19 +28,8 @@
// GetDebugKubeconfig issues kubeconfigs with arbitrary identities and groups for debugging
rpc GetDebugKubeconfig(GetDebugKubeconfigRequest) returns (GetDebugKubeconfigResponse);
- // GetLogs Returns historical and/or streaming logs for a given DN with given filters from the system global
- // LogTree.
- //
- // For more information about this API, see //metropolis/pkg/logtree. But, in summary:
- // - All logging is performed to a DN (distinguished name), which is a dot-delimited string like foo.bar.baz.
- // - Log entries can be either raw (coming from unstructured logging from an external service, like a running
- // process) or leveled (emitted by Metropolis code with a source line, timestamp, and severity).
- // - The DNs form a tree of logging nodes - and when requesting logs, a given subtree of DNs can be requested,
- // instead of just a given DN.
- // - All supervised processes live at `root.<supervisor DN>`. For more example paths, see the console logs of
- // a running Metropolis node, or request all logs (at DN "").
- //
- // TODO(q3k): move method and its related messages to the non-debug node endpoint once we have one.
+ // A reimplementation of metropolis.api.NodeManagement.Logs that's available
+ // before the node starts up the management service.
rpc GetLogs(GetLogsRequest) returns (stream GetLogsResponse);
// Trace enables tracing of Metropolis using the Linux ftrace infrastructure.
diff --git a/metropolis/proto/api/management.proto b/metropolis/proto/api/management.proto
index 3c869a9..5b66311 100644
--- a/metropolis/proto/api/management.proto
+++ b/metropolis/proto/api/management.proto
@@ -185,6 +185,22 @@
// NodeManagement runs on every node of the cluster and providers management
// and troubleshooting RPCs to operators. All requests must be authenticated.
service NodeManagement {
+ // GetLogs Returns historical and/or streaming logs for a given DN with given
+ // filters from the system global LogTree.
+ //
+ // For more information about this API, see //metropolis/pkg/logtree. But, in
+ // summary:
+ // - All logging is performed to a DN (distinguished name), which is a
+ // dot-delimited string like foo.bar.baz.
+ // - Log entries can be either raw (coming from unstructured logging from
+ // an external service, like a running process) or leveled (emitted by
+ // Metropolis code with a source line, timestamp, and severity).
+ // - The DNs form a tree of logging nodes - and when requesting logs, a
+ // given subtree of DNs can be requested, instead of just a given DN.
+ // - All supervised processes live at `root.<supervisor DN>`. For more
+ // example paths, see the console logs of a running Metropolis node, or
+ // request all logs (at DN "").
+ //
rpc Logs(GetLogsRequest) returns (stream GetLogsResponse) {
option (metropolis.proto.ext.authorization) = {
need: PERMISSION_READ_NODE_LOGS
@@ -192,58 +208,12 @@
}
}
-
-// Severity level corresponding to //metropolis/pkg/logtree.Severity.
-enum LeveledLogSeverity {
- INVALID = 0;
- INFO = 1;
- WARNING = 2;
- ERROR = 3;
- FATAL = 4;
-}
-
-// Filter set when requesting logs for a given DN. This message is equivalent to
-// the following GADT enum:
-// data LogFilter = WithChildren
-// | OnlyRaw
-// | OnlyLeveled
-// | LeveledWithMinimumSeverity(Severity)
-//
-// Multiple LogFilters can be chained/combined when requesting logs, as long as
-// they do not conflict.
-message LogFilter {
- // Entries will be returned not only for the given DN, but all child DNs as
- // well. For instance, if the requested DN is foo, entries logged to foo,
- // foo.bar and foo.bar.baz will all be returned.
- message WithChildren {
- }
- // Only raw logging entries will be returned. Conflicts with OnlyLeveled
- // filters.
- message OnlyRaw {
- }
- // Only leveled logging entries will be returned. Conflicts with OnlyRaw
- // filters.
- message OnlyLeveled {
- }
- // If leveled logs are returned, all entries at severity lower than `minimum`
- // will be discarded.
- message LeveledWithMinimumSeverity {
- LeveledLogSeverity minimum = 1;
- }
- oneof filter {
- WithChildren with_children = 1;
- OnlyRaw only_raw = 3;
- OnlyLeveled only_leveled = 4;
- LeveledWithMinimumSeverity leveled_with_minimum_severity = 5;
- }
-}
-
message GetLogsRequest {
// DN from which to request logs. All supervised runnables live at `root.`,
// the init code lives at `init.`.
string dn = 1;
// Filters to apply to returned data.
- repeated LogFilter filters = 2;
+ repeated metropolis.proto.common.LogFilter filters = 2;
enum BacklogMode {
BACKLOG_INVALID = 0;
@@ -259,39 +229,22 @@
enum StreamMode {
STREAM_INVALID = 0;
- // No streaming entries, gRPC stream will be closed as soon as all backlog data is served.
+ // No streaming entries, gRPC stream will be closed as soon as all backlog
+ // data is served.
STREAM_DISABLE = 1;
- // Entries will be streamed as early as available right after all backlog data is served.
+ // Entries will be streamed as early as available right after all backlog
+ // data is served.
STREAM_UNBUFFERED = 2;
}
StreamMode stream_mode = 5;
}
-message LogEntry {
- message Leveled {
- repeated string lines = 1;
- google.protobuf.Timestamp timestamp = 2;
- LeveledLogSeverity severity = 3;
- string location = 4;
- }
- message Raw {
- string data = 1;
- int64 original_length = 2;
- }
-
- string dn = 1;
- oneof kind {
- Leveled leveled = 2;
- Raw raw = 3;
- }
-}
-
message GetLogsResponse {
- // Entries from the requested historical entries (via WithBackLog). They will all be served before the first
- // stream_entries are served (if any).
- repeated LogEntry backlog_entries = 1;
- // Entries streamed as they arrive. Currently no server-side buffering is enabled, instead every line is served
- // as early as it arrives. However, this might change in the future, so this behaviour cannot be depended
- // upon.
- repeated LogEntry stream_entries = 2;
+ // Entries from the requested historical entries (via WithBackLog). They will
+ // all be served before the first stream_entries are served (if any).
+ repeated metropolis.proto.common.LogEntry backlog_entries = 1;
+ // Entries streamed as they arrive. Currently no server-side buffering is
+ // enabled, instead every line is served as early as it arrives. However, this
+ // might change in the future, so this behaviour cannot be depended upon.
+ repeated metropolis.proto.common.LogEntry stream_entries = 2;
}
\ No newline at end of file
diff --git a/metropolis/proto/common/common.proto b/metropolis/proto/common/common.proto
index 183f790..a884dff 100644
--- a/metropolis/proto/common/common.proto
+++ b/metropolis/proto/common/common.proto
@@ -189,3 +189,77 @@
// mesh, and are programmed by other nodes into their wireguard peer config.
repeated Prefix prefixes = 2;
}
+
+// Severity level corresponding to //metropolis/pkg/logtree.Severity.
+enum LeveledLogSeverity {
+ INVALID = 0;
+ INFO = 1;
+ WARNING = 2;
+ ERROR = 3;
+ FATAL = 4;
+}
+
+// Filter set when requesting logs for a given DN. This message is equivalent to
+// the following GADT enum:
+// data LogFilter = WithChildren
+// | OnlyRaw
+// | OnlyLeveled
+// | LeveledWithMinimumSeverity(Severity)
+//
+// Multiple LogFilters can be chained/combined when requesting logs, as long as
+// they do not conflict.
+message LogFilter {
+ // Entries will be returned not only for the given DN, but all child DNs as
+ // well. For instance, if the requested DN is foo, entries logged to foo,
+ // foo.bar and foo.bar.baz will all be returned.
+ message WithChildren {
+ }
+ // Only raw logging entries will be returned. Conflicts with OnlyLeveled
+ // filters.
+ message OnlyRaw {
+ }
+ // Only leveled logging entries will be returned. Conflicts with OnlyRaw
+ // filters.
+ message OnlyLeveled {
+ }
+ // If leveled logs are returned, all entries at severity lower than `minimum`
+ // will be discarded.
+ message LeveledWithMinimumSeverity {
+ LeveledLogSeverity minimum = 1;
+ }
+ oneof filter {
+ WithChildren with_children = 1;
+ OnlyRaw only_raw = 3;
+ OnlyLeveled only_leveled = 4;
+ LeveledWithMinimumSeverity leveled_with_minimum_severity = 5;
+ }
+}
+
+// LogEntry corresponding to logtree.LogEntry in //metropolis/pkg/logtree.
+message LogEntry {
+ // A leveled log entry emitted from a compatible system, eg. Metorpolis code
+ // or a klog-parsed line.
+ message Leveled {
+ repeated string lines = 1;
+ google.protobuf.Timestamp timestamp = 2;
+ LeveledLogSeverity severity = 3;
+ // Source of the error, expressed as file:line.
+ string location = 4;
+ }
+ // Raw log entry, captured from an external system without parting. Might
+ // contain some timestamp/level/origin information embedded in data. Data
+ // contained within should be treated as unsanitized external data.
+ message Raw {
+ string data = 1;
+ // Original length of line, set if data was truncated.
+ int64 original_length = 2;
+ }
+
+ // Origin DN.
+ string dn = 1;
+ oneof kind {
+ Leveled leveled = 2;
+ Raw raw = 3;
+ }
+}
+