This repository has been archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Backport 5.2] graphqlbackend/telemetry: add query for recently expor…
…ted events (#59041) * graphqlbackend/telemetry: add query for recently exported events (#57029) Adds a `telemetry { exportedEvents { ... } }` query that allows a site admin to view recently exported events, before they are removed from the queue by the queue cleaner after `TELEMETRY_GATEWAY_EXPORTER_EXPORTED_EVENTS_RETENTION`, which defaults to 24 hours. This is very different from `event_logs` because it provides a `protojson` rendering of the "true" event payload - the data shown is exactly the data that was exported (except the export happens over proto), whereas the `event_logs` equivalent is translated from the raw data and may be missing some things. The new query and resolver supports pagination. This is useful in local development to see events without interrogating the telemetry-gateway's local dev logging mode or connecting it to a real telemetry-gateway and querying BigQuery. This can also be useful if a customer wants to see what is getting exported - right now, there's no easy way to do so without asking someone at Sourcegraph to check BigQuery, or for the customer to parse the raw proto payloads in the database themselves. I have a feeling this ask will eventually arise as we roll out v2 telemetry adoption more broadly. Closes https://github.com/sourcegraph/sourcegraph/issues/57027 ## Test plan Unit and integration tests, and some manual testing with `sg start` and running some searches: ![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/ab39d9ad-829f-475a-b093-411edbcdf579) --------- Co-authored-by: Joe Chen <[email protected]> (cherry picked from commit 5bfda07) * fixup --------- Co-authored-by: Robert Lin <[email protected]> Co-authored-by: Warren Gifford <[email protected]>
- Loading branch information
1 parent
ac23781
commit e464b48
Showing
14 changed files
with
585 additions
and
357 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
cmd/frontend/internal/telemetry/resolvers/exportedevents_resolvers.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package resolvers | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"time" | ||
|
||
"github.com/graph-gophers/graphql-go" | ||
"github.com/graph-gophers/graphql-go/relay" | ||
"google.golang.org/protobuf/encoding/protojson" | ||
|
||
"github.com/sourcegraph/sourcegraph/cmd/frontend/graphqlbackend" | ||
"github.com/sourcegraph/sourcegraph/cmd/frontend/graphqlbackend/graphqlutil" | ||
"github.com/sourcegraph/sourcegraph/internal/database" | ||
"github.com/sourcegraph/sourcegraph/internal/gqlutil" | ||
"github.com/sourcegraph/sourcegraph/lib/errors" | ||
"github.com/sourcegraph/sourcegraph/lib/pointers" | ||
) | ||
|
||
func decodeExportedEventsCursor(cursor string) (*time.Time, error) { | ||
cursor, err := graphqlutil.DecodeCursor(&cursor) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "invalid cursor") | ||
} | ||
t, err := time.Parse(time.RFC3339, cursor) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "invalid cursor data") | ||
} | ||
return &t, nil | ||
} | ||
|
||
func encodeExportedEventsCursor(t time.Time) *graphqlutil.PageInfo { | ||
ts, err := t.MarshalText() | ||
if err != nil { | ||
return graphqlutil.HasNextPage(false) | ||
} | ||
return graphqlutil.EncodeCursor(pointers.Ptr(string(ts))) | ||
} | ||
|
||
type ExportedEventResolver struct { | ||
event database.ExportedTelemetryEvent | ||
} | ||
|
||
var _ graphqlbackend.ExportedEventResolver = &ExportedEventResolver{} | ||
|
||
func (r *ExportedEventResolver) ID() graphql.ID { | ||
return relay.MarshalID("ExportedEvent", r.event.ID) | ||
} | ||
|
||
func (r *ExportedEventResolver) ExportedAt() gqlutil.DateTime { | ||
return gqlutil.DateTime{Time: r.event.ExportedAt} | ||
} | ||
|
||
func (r *ExportedEventResolver) Payload() (graphqlbackend.JSONValue, error) { | ||
payload, err := protojson.Marshal(r.event.Payload) | ||
if err != nil { | ||
return graphqlbackend.JSONValue{Value: struct{}{}}, | ||
errors.Wrapf(err, "failed to marshal payload of event ID %q", r.event.ID) | ||
} | ||
return graphqlbackend.JSONValue{Value: json.RawMessage(payload)}, nil | ||
} | ||
|
||
type ExportedEventsConnectionResolver struct { | ||
ctx context.Context | ||
diagnostics database.TelemetryEventsExportQueueDiagnosticsStore | ||
|
||
limit int | ||
exported []database.ExportedTelemetryEvent | ||
} | ||
|
||
var _ graphqlbackend.ExportedEventsConnectionResolver = &ExportedEventsConnectionResolver{} | ||
|
||
func (r *ExportedEventsConnectionResolver) Nodes() []graphqlbackend.ExportedEventResolver { | ||
nodes := make([]graphqlbackend.ExportedEventResolver, len(r.exported)) | ||
for i, event := range r.exported { | ||
nodes[i] = &ExportedEventResolver{event: event} | ||
} | ||
return nodes | ||
} | ||
|
||
func (r *ExportedEventsConnectionResolver) TotalCount() (int32, error) { | ||
count, err := r.diagnostics.CountRecentlyExported(r.ctx) | ||
if err != nil { | ||
return 0, errors.Wrap(err, "CountRecentlyExported") | ||
} | ||
return int32(count), nil | ||
} | ||
|
||
func (r *ExportedEventsConnectionResolver) PageInfo() *graphqlutil.PageInfo { | ||
if len(r.exported) == 0 || len(r.exported) < r.limit { | ||
return graphqlutil.HasNextPage(false) | ||
} | ||
lastEvent := r.exported[len(r.exported)-1] | ||
return encodeExportedEventsCursor(lastEvent.Timestamp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.