fix(logging): Entries has a 24H default filter (#3120)

* feat(logging): List entries has a 24H default filter
diff --git a/logging/logadmin/logadmin.go b/logging/logadmin/logadmin.go
index 0cfc8f3..d6ffc31 100644
--- a/logging/logadmin/logadmin.go
+++ b/logging/logadmin/logadmin.go
@@ -208,8 +208,8 @@
 // "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 @@
 	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 6dddbe9..dcb4bcd 100644
--- a/logging/logadmin/logadmin_test.go
+++ b/logging/logadmin/logadmin_test.go
@@ -262,27 +262,31 @@
 }
 
 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{