diff --git a/internal/pkg/source/entry.go b/internal/pkg/source/entry.go index 8844443..8d1d333 100644 --- a/internal/pkg/source/entry.go +++ b/internal/pkg/source/entry.go @@ -3,6 +3,8 @@ package source import ( "bytes" "encoding/json" + "strings" + "unicode" "github.com/charmbracelet/bubbles/table" "github.com/valyala/fastjson" @@ -79,15 +81,29 @@ func ParseLogEntry(line json.RawMessage) LogEntry { return LogEntry{ Line: line, Time: "-", - Message: string(line), + Message: formatMessage(string(line)), Level: LevelUnknown, } } return LogEntry{ Line: line, - Time: extractTime(value), - Message: extractMessage(value), + Time: formatMessage(extractTime(value)), + Message: formatMessage(extractMessage(value)), Level: extractLevel(value), } } + +func formatMessage(msg string) string { + msg = strings.NewReplacer("\n", "\\n", "\t", "\\t").Replace(msg) + + msg = strings.Map(func(r rune) rune { + if unicode.IsPrint(r) { + return r + } + + return -1 + }, msg) + + return msg +} diff --git a/internal/pkg/source/entry_test.go b/internal/pkg/source/entry_test.go index 1da1a93..dd8b2ae 100644 --- a/internal/pkg/source/entry_test.go +++ b/internal/pkg/source/entry_test.go @@ -75,6 +75,14 @@ func TestParseLogEntry(t *testing.T) { assert.Equal(t, "msg", logEntry.Message) }, + }, { + Name: "message_special_rune", + JSON: `{"message":"mes` + string(rune(1)) + `sage"}`, + Assert: func(tb testing.TB, logEntry source.LogEntry) { + tb.Helper() + + assert.Equal(t, "message", logEntry.Message) + }, }, { Name: "error", JSON: `{"error":"error"}`, diff --git a/internal/pkg/source/helper.go b/internal/pkg/source/helper.go index bbfc78e..a7fa8ea 100644 --- a/internal/pkg/source/helper.go +++ b/internal/pkg/source/helper.go @@ -10,7 +10,7 @@ import ( func extractTime(value *fastjson.Value) string { timeValue := extractValue(value, "timestamp", "time", "t") if timeValue != "" { - return strings.TrimSpace(timeValue) + return formatMessage(strings.TrimSpace(timeValue)) } return "-" @@ -19,7 +19,7 @@ func extractTime(value *fastjson.Value) string { func extractLevel(value *fastjson.Value) Level { level := extractValue(value, "level", "lvl") - return ParseLevel(level) + return ParseLevel(formatMessage(level)) } func extractValue(value *fastjson.Value, keys ...string) string {