fix: machine logs timestamp parsing and streaming for systemd <v255

This commit is contained in:
Pasha Sviderski
2026-04-23 17:31:31 +10:00
parent f379bf4c14
commit 50057c42e0
4 changed files with 132 additions and 16 deletions
+22 -9
View File
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"slices"
"strconv"
"time"
"github.com/psviderski/uncloud/pkg/api"
@@ -33,17 +34,12 @@ func Logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (<-chan
}
func entry(data []byte) api.LogEntry {
// 2025-10-12T11:03:27+02:00 systemd[1]:
// 1758193407.686964 systemd[1]: ...
timestamp := time.Time{}
message := data
if len(data) > 30 && data[4] == '-' && data[7] == '-' && data[10] == 'T' {
timestampPart, messagePart, found := bytes.Cut(data, []byte(" "))
var err error
if found {
timestamp, err = time.Parse(time.RFC3339Nano, string(timestampPart))
if err != nil {
timestamp = time.Time{}
}
if timestampPart, messagePart, found := bytes.Cut(data, []byte(" ")); found {
if t, ok := parseUnixTimestamp(timestampPart); ok {
timestamp = t
message = messagePart
}
}
@@ -54,3 +50,20 @@ func entry(data []byte) api.LogEntry {
Stream: api.LogStreamStdout,
}
}
// parseUnixTimestamp parses a journalctl short-unix timestamp "SSSSSSSSSS.UUUUUU" with microsecond precision.
func parseUnixTimestamp(b []byte) (time.Time, bool) {
secPart, usecPart, found := bytes.Cut(b, []byte("."))
if !found {
return time.Time{}, false
}
sec, err := strconv.ParseInt(string(secPart), 10, 64)
if err != nil {
return time.Time{}, false
}
usec, err := strconv.ParseInt(string(usecPart), 10, 64)
if err != nil {
return time.Time{}, false
}
return time.Unix(sec, usec*1000), true
}