core: plug logtree into NodeDebugService

This introduces a new Proto API for accessing debug logs. Currently this
is implemented to be used by the debug service. However, these proto
definitions will likely be reused for production cluster APIs.

The implementation mostly consists of adding the proto, implementing
to/from conversion methods, and altering the debug service to use the
new API.

We also move all of the debug service implementation into a separate file,
to slightly clean up main.go. This produces an unfortunately colorful
diff, but it's just moving code around.

Test Plan: Manually tested using the dbg tool. We currently don't properly test the debug service. I suppose we should do that for the production cluster APIs, and just keep on going for now.

X-Origin-Diff: phab/D649
GitOrigin-RevId: ac454681e4b72b2876e313b3aeababa179eb1fa3
diff --git a/core/pkg/logbuffer/BUILD.bazel b/core/pkg/logbuffer/BUILD.bazel
index fb7512a..958389e 100644
--- a/core/pkg/logbuffer/BUILD.bazel
+++ b/core/pkg/logbuffer/BUILD.bazel
@@ -8,6 +8,7 @@
     ],
     importpath = "git.monogon.dev/source/nexantic.git/core/pkg/logbuffer",
     visibility = ["//visibility:public"],
+    deps = ["//core/proto/api:go_default_library"],
 )
 
 go_test(
diff --git a/core/pkg/logbuffer/linebuffer.go b/core/pkg/logbuffer/linebuffer.go
index 6ee7d6b..fa4dc33 100644
--- a/core/pkg/logbuffer/linebuffer.go
+++ b/core/pkg/logbuffer/linebuffer.go
@@ -21,6 +21,8 @@
 	"fmt"
 	"strings"
 	"sync"
+
+	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
 )
 
 // Line is a line stored in the log buffer - a string, that has been perhaps truncated (due to exceeded limits).
@@ -43,6 +45,29 @@
 	return l.Data
 }
 
+// ProtoLog returns a Logging-specific protobuf structure.
+func (l *Line) ProtoLog() *apb.LogEntry_Raw {
+	return &apb.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) {
+	if raw.OriginalLength < int64(len(raw.Data)) {
+		return nil, fmt.Errorf("original_length smaller than length of data")
+	}
+	originalLength := int(raw.OriginalLength)
+	if int64(originalLength) < raw.OriginalLength {
+		return nil, fmt.Errorf("original_length larger than native int size")
+	}
+	return &Line{
+		Data:           raw.Data,
+		OriginalLength: originalLength,
+	}, nil
+}
+
 // LineBuffer is a io.WriteCloser that will call a given callback every time a line is completed.
 type LineBuffer struct {
 	maxLineLength int