Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions example.jlv.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// AM/PM mark: "PM"
//
// More details: https://go.dev/src/time/format.go.
"time_format": "2006-01-02T15:04:05Z07:00"
"timeFormat": "2006-01-02T15:04:05Z07:00"
},
{
"title": "Level",
Expand Down Expand Up @@ -65,13 +65,15 @@
"width": 0
}
],
// Show logs in reverse order by default.
"isReverseDefault": true,
// Time layouts to reformat.
//
// If the time field has been parsed to any of the specified layouts,
// it will be formatted according to "time_format" configuration.
// it will be formatted according to "timeFormat" configuration.
//
// See: https://pkg.go.dev/time#pkg-constants.
"time_layouts": [
"timeLayouts": [
"01/02 03:04:05PM '06 -0700",
"Mon Jan _2 15:04:05 2006",
"Mon Jan _2 15:04:05 MST 2006",
Expand Down
18 changes: 15 additions & 3 deletions internal/app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,26 @@ import (

const testVersion = "v0.0.1"

func newTestModel(tb testing.TB, content []byte) tea.Model {
type configSetter func(*config.Config)

func newTestModel(
tb testing.TB,
content []byte,
configSetters ...configSetter,
) tea.Model {
tb.Helper()

testFile := tests.RequireCreateFile(tb, content)

inputSource, err := source.File(testFile, config.GetDefaultConfig())
cfg := config.GetDefaultConfig()

for _, set := range configSetters {
set(cfg)
}

inputSource, err := source.File(testFile, cfg)
require.NoError(tb, err)
model := app.NewModel(testFile, config.GetDefaultConfig(), testVersion)
model := app.NewModel(testFile, cfg, testVersion)

entries, err := inputSource.ParseLogEntries()
require.NoError(tb, err)
Expand Down
4 changes: 2 additions & 2 deletions internal/app/stateloaded.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func newStateViewLogs(
table := newLogsTableModel(
application,
logEntries,
true, // follow.
true, // reverse.
true, // follow.
application.Config.IsReverseDefault, // reverse.
)

return StateLoadedModel{
Expand Down
15 changes: 13 additions & 2 deletions internal/app/stateloaded_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ func TestStateLoadedEmpty(t *testing.T) {
func TestStateLoaded(t *testing.T) {
t.Parallel()

setup := func() tea.Model {
setup := func(configSetters ...configSetter) tea.Model {
const jsonFile = `{"time":"1970-01-01T00:00:00.00","level":"INFO","message": "test"}`

model := newTestModel(t, []byte(jsonFile))
model := newTestModel(t, []byte(jsonFile), configSetters...)

_, ok := model.(app.StateLoadedModel)
require.Truef(t, ok, "%s", model)
Expand Down Expand Up @@ -111,6 +111,17 @@ func TestStateLoaded(t *testing.T) {
assert.Contains(t, view, "reverse")
})

t.Run("label_reverse_disabled_in_config", func(t *testing.T) {
t.Parallel()

model := setup(func(cfg *config.Config) {
cfg.IsReverseDefault = false
})

view := model.View()
assert.NotContains(t, view, "reverse")
})

t.Run("label_not_reverse", func(t *testing.T) {
t.Parallel()

Expand Down
23 changes: 21 additions & 2 deletions internal/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ type Config struct {
Path string `json:"-"`

Fields []Field `json:"fields" validate:"min=1"`

TimeLayoutsDeprecated []string `json:"time_layouts,omitempty"`
// TimeLayouts to reformat.
TimeLayouts []string `json:"time_layouts"`
TimeLayouts []string `json:"timeLayouts"`

IsReverseDefault bool `json:"isReverseDefault"`

CustomLevelMapping map[string]string `json:"customLevelMapping"`

Expand Down Expand Up @@ -55,7 +59,9 @@ type Field struct {
Kind FieldKind `json:"kind" validate:"required,oneof=time message numerictime secondtime millitime microtime level any"`
References []string `json:"ref" validate:"min=1,dive,required"`
Width int `json:"width" validate:"min=0"`
TimeFormat *string `json:"time_format,omitempty"`

TimeFormatDeprecated *string `json:"time_format,omitempty"`
TimeFormat *string `json:"timeFormat,omitempty"`
}

// GetDefaultConfig returns the configuration with default values.
Expand Down Expand Up @@ -102,6 +108,7 @@ func GetDefaultConfig() *Config {
Kind: FieldKindMessage,
References: []string{"$.message", "$.msg", "$.error", "$.err"},
}},
IsReverseDefault: true,
}
}

Expand Down Expand Up @@ -165,6 +172,18 @@ func readConfigFromFile(path string) (cfg *Config, err error) {

cfg.Path = path

if len(cfg.TimeLayoutsDeprecated) != 0 {
cfg.TimeLayouts = cfg.TimeLayoutsDeprecated
}

for i, f := range cfg.Fields {
if f.TimeFormatDeprecated != nil && *f.TimeFormatDeprecated != "" {
f.TimeFormat = f.TimeFormatDeprecated
}

cfg.Fields[i] = f
}

return cfg, nil
}

Expand Down
44 changes: 42 additions & 2 deletions internal/pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func ExampleGetDefaultConfig() {
// "$[\"@timestamp\"]"
// ],
// "width": 30,
// "time_format": "2006-01-02T15:04:05Z07:00"
// "timeFormat": "2006-01-02T15:04:05Z07:00"
// },
// {
// "title": "Level",
Expand All @@ -138,7 +138,7 @@ func ExampleGetDefaultConfig() {
// "width": 0
// }
// ],
// "time_layouts": [
// "timeLayouts": [
// "01/02 03:04:05PM '06 -0700",
// "Mon Jan _2 15:04:05 2006",
// "Mon Jan _2 15:04:05 MST 2006",
Expand All @@ -157,6 +157,7 @@ func ExampleGetDefaultConfig() {
// "2006-01-02 15:04:05",
// "2006-01-02"
// ],
// "isReverseDefault": true,
// "customLevelMapping": {
// "10": "trace",
// "20": "debug",
Expand Down Expand Up @@ -395,3 +396,42 @@ func TestByteSizeParseFailed(t *testing.T) {
require.Error(t, err)
})
}

func TestReadTimeLayoutsDeprecated(t *testing.T) {
t.Parallel()

cfg := config.GetDefaultConfig()
cfg.TimeLayoutsDeprecated = []string{time.Layout}
cfg.TimeLayouts = nil

configJSON := tests.RequireEncodeJSON(t, cfg)
fileFirst := tests.RequireCreateFile(t, configJSON)

actual, err := config.Read(fileFirst)
if assert.NoError(t, err) {
assert.ElementsMatch(t, actual.TimeLayouts, cfg.TimeLayoutsDeprecated)
}
}

func TestReadTimeFormatDeprecated(t *testing.T) {
t.Parallel()

timeFormat := time.Layout

cfg := config.GetDefaultConfig()
cfg.Fields = []config.Field{{
Title: "Time",
Kind: config.FieldKindNumericTime,
References: []string{"$.timestamp", "$.time", "$.t", "$.ts", "$[\"@timestamp\"]"},
Width: 30,
TimeFormatDeprecated: &timeFormat,
}}

configJSON := tests.RequireEncodeJSON(t, cfg)
fileFirst := tests.RequireCreateFile(t, configJSON)

actual, err := config.Read(fileFirst)
if assert.NoError(t, err) {
assert.Equal(t, timeFormat, *actual.Fields[0].TimeFormat)
}
}
Loading