Skip to content
Open
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
1 change: 1 addition & 0 deletions docs/victorialogs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ according to the following docs:
* FEATURE: [alerts](https://github.com/VictoriaMetrics/VictoriaLogs/blob/master/deployment/docker/rules): add new alerting rules `PersistentQueueRunsOutOfSpaceIn12Hours` and `PersistentQueueRunsOutOfSpaceIn4Hours` for `vlagent` persistent queue capacity. These alerts help users to take proactive actions before `vlagent` starts dropping logs due to insufficient persistent queue space. See [#10193](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10193)
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): remove the `Date format` setting and always display timestamps with nanosecond precision. See [#1161](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1161).

* BUGFIX: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/): fix [`sort by (_time) limit N`](https://docs.victoriametrics.com/victorialogs/logsql/#sort-pipe) returning logs out of order when the query pipeline included pipes like [`unpack_json`](https://docs.victoriametrics.com/victorialogs/logsql/#unpack_json-pipe) that overwrite `_time`. See [#1360](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1360).
* BUGFIX: [vlagent](https://docs.victoriametrics.com/victorialogs/vlagent/): hide sensitive values passed via `-remoteWrite.proxyURL` in `/metrics`, `/flags`, and startup logs. Previously these values could be exposed in plain text. See [#1320](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1320).
* BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): sanitize markdown URLs in logs rendered with `markdown parsing` enabled, allowing only `http`, `https`, `mailto`, and `tel` schemes for active links and images. See [#1313](https://github.com/VictoriaMetrics/VictoriaLogs/pull/1313).
* BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): improve context view highlight visibility in dark theme. The selected log entry is now highlighted with a more visible blue tint instead of barely visible gray background. See [#1196](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1196).
Expand Down
2 changes: 1 addition & 1 deletion lib/logstorage/pipe_sort_topk.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ func topkLess(ps *pipeSort, a, b *pipeTopkRow) bool {
bb.B = marshalTimestampRFC3339NanoString(bb.B[:0], a.timestamp)
vA = bytesutil.ToUnsafeString(bb.B)
} else if isTimeB[i] {
bb.B = marshalTimestampRFC3339NanoString(bb.B[:0], a.timestamp)
bb.B = marshalTimestampRFC3339NanoString(bb.B[:0], b.timestamp)
vB = bytesutil.ToUnsafeString(bb.B)
}

Expand Down
66 changes: 66 additions & 0 deletions lib/logstorage/pipe_sort_topk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,72 @@ import (
"testing"
)

func TestTopkLess(t *testing.T) {
parseTimestamp := func(s string) int64 {
t.Helper()

timestamp, ok := TryParseTimestampRFC3339Nano(s)
if !ok {
t.Fatalf("cannot parse timestamp %q", s)
}
return timestamp
}

ps := &pipeSort{
byFields: []*bySortField{
{name: "_time"},
},
}
psDesc := &pipeSort{
byFields: []*bySortField{
{name: "_time"},
},
isDesc: true,
}

stringRow := func(s string) *pipeTopkRow {
return &pipeTopkRow{
byColumns: []string{s},
byColumnsIsTime: []bool{false},
}
}
timeRow := func(s string) *pipeTopkRow {
return &pipeTopkRow{
byColumns: []string{""},
byColumnsIsTime: []bool{true},
timestamp: parseTimestamp(s),
}
}
f := func(ps *pipeSort, a, b *pipeTopkRow, resultExpected bool) {
t.Helper()

result := topkLess(ps, a, b)
if result != resultExpected {
t.Fatalf("unexpected result for topkLess(%#v, %#v); got %v; want %v", a, b, result, resultExpected)
}
}

// string time vs string time
f(ps, stringRow("2026-04-25T10:00:54Z"), stringRow("2026-04-25T10:01:54Z"), true)
f(ps, stringRow("2026-04-25T10:01:54Z"), stringRow("2026-04-25T10:00:54Z"), false)

// real time vs real time
f(ps, timeRow("2026-04-25T10:00:54Z"), timeRow("2026-04-25T10:01:54Z"), true)
f(ps, timeRow("2026-04-25T10:01:54Z"), timeRow("2026-04-25T10:00:54Z"), false)

// string time is smaller than real time
f(ps, stringRow("2026-04-25T10:00:54Z"), timeRow("2026-04-25T10:01:54Z"), true)
f(ps, timeRow("2026-04-25T10:01:54Z"), stringRow("2026-04-25T10:00:54Z"), false)

// real time is smaller than string time
f(ps, timeRow("2026-04-25T10:00:54Z"), stringRow("2026-04-25T10:01:54Z"), true)
f(ps, stringRow("2026-04-25T10:01:54Z"), timeRow("2026-04-25T10:00:54Z"), false)

// string time vs real time with descending sort
f(psDesc, stringRow("2026-04-25T10:00:54Z"), timeRow("2026-04-25T10:01:54Z"), false)
f(psDesc, timeRow("2026-04-25T10:01:54Z"), stringRow("2026-04-25T10:00:54Z"), true)
Comment thread
cuongleqq marked this conversation as resolved.
}

func TestLessString(t *testing.T) {
f := func(a, b string, resultExpected bool) {
t.Helper()
Expand Down