diff --git a/logging/logadmin/logadmin.go b/logging/logadmin/logadmin.go index 0cfc8f3a376..d6ffc31f045 100644 --- a/logging/logadmin/logadmin.go +++ b/logging/logadmin/logadmin.go @@ -208,8 +208,8 @@ func (rn resourceNames) set(r *logpb.ListLogEntriesRequest) { // "projects/PROJECT-ID/logs/LOG-ID". Forward slashes in LOG-ID must be // replaced by %2F before calling Filter. // -// Timestamps in the filter string must be written in RFC 3339 format. See the -// timestamp example. +// Timestamps in the filter string must be written in RFC 3339 format. By default, +// timestamp filters for the past 24 hours. func Filter(f string) EntriesOption { return filter(f) } type filter string @@ -245,9 +245,25 @@ func listLogEntriesRequest(parent string, opts []EntriesOption) *logpb.ListLogEn for _, opt := range opts { opt.set(req) } + req.Filter = defaultTimestampFilter(req.Filter) return req } +// defaultTimestampFilter returns a timestamp filter that looks back 24 hours in the past. +// This default setting is consistent with documentation. Note: user filters containing 'timestamp' +// substring disables this default timestamp filter, e.g. `textPayload: "timestamp"` +func defaultTimestampFilter(filter string) string { + dayAgo := time.Now().Add(-24 * time.Hour).UTC() + switch { + case len(filter) == 0: + return fmt.Sprintf(`timestamp >= "%s"`, dayAgo.Format(time.RFC3339)) + case !strings.Contains(strings.ToLower(filter), "timestamp"): + return fmt.Sprintf(`%s AND timestamp >= "%s"`, filter, dayAgo.Format(time.RFC3339)) + default: + return filter + } +} + // An EntryIterator iterates over log entries. type EntryIterator struct { it *vkit.LogEntryIterator diff --git a/logging/logadmin/logadmin_test.go b/logging/logadmin/logadmin_test.go index 6dddbe912a6..dcb4bcd91be 100644 --- a/logging/logadmin/logadmin_test.go +++ b/logging/logadmin/logadmin_test.go @@ -262,27 +262,31 @@ func TestFromLogEntry(t *testing.T) { } func TestListLogEntriesRequest(t *testing.T) { + dayAgo := time.Now().Add(-24 * time.Hour).UTC().Format(time.RFC3339) for _, test := range []struct { opts []EntriesOption resourceNames []string filter string orderBy string }{ - // Default is client's project ID, empty filter and orderBy. - {nil, []string{"projects/PROJECT_ID"}, "", ""}, + // Default is client's project ID, 24 hour lookback, and orderBy. + {nil, []string{"projects/PROJECT_ID"}, `timestamp >= "` + dayAgo + `"`, ""}, + // Timestamp default does not override user's filter + {[]EntriesOption{NewestFirst(), Filter(`timestamp > "2020-10-30T15:39:09Z"`)}, + []string{"projects/PROJECT_ID"}, `timestamp > "2020-10-30T15:39:09Z"`, "timestamp desc"}, {[]EntriesOption{NewestFirst(), Filter("f")}, - []string{"projects/PROJECT_ID"}, "f", "timestamp desc"}, + []string{"projects/PROJECT_ID"}, `f AND timestamp >= "` + dayAgo + `"`, "timestamp desc"}, {[]EntriesOption{ProjectIDs([]string{"foo"})}, - []string{"projects/foo"}, "", ""}, + []string{"projects/foo"}, `timestamp >= "` + dayAgo + `"`, ""}, {[]EntriesOption{ResourceNames([]string{"folders/F", "organizations/O"})}, - []string{"folders/F", "organizations/O"}, "", ""}, + []string{"folders/F", "organizations/O"}, `timestamp >= "` + dayAgo + `"`, ""}, {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})}, - []string{"projects/foo"}, "f", "timestamp desc"}, + []string{"projects/foo"}, `f AND timestamp >= "` + dayAgo + `"`, "timestamp desc"}, {[]EntriesOption{NewestFirst(), Filter("f"), ProjectIDs([]string{"foo"})}, - []string{"projects/foo"}, "f", "timestamp desc"}, + []string{"projects/foo"}, `f AND timestamp >= "` + dayAgo + `"`, "timestamp desc"}, // If there are repeats, last one wins. {[]EntriesOption{NewestFirst(), Filter("no"), ProjectIDs([]string{"foo"}), Filter("f")}, - []string{"projects/foo"}, "f", "timestamp desc"}, + []string{"projects/foo"}, `f AND timestamp >= "` + dayAgo + `"`, "timestamp desc"}, } { got := listLogEntriesRequest("projects/PROJECT_ID", test.opts) want := &logpb.ListLogEntriesRequest{