Skip to content

Commit f38950a

Browse files
feat: add delete commands to logcli (#18375)
1 parent 7de56e2 commit f38950a

10 files changed

Lines changed: 2411 additions & 0 deletions

File tree

‎cmd/logcli/main.go‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/prometheus/common/version"
1717

1818
"github.com/grafana/loki/v3/pkg/logcli/client"
19+
"github.com/grafana/loki/v3/pkg/logcli/delete"
1920
"github.com/grafana/loki/v3/pkg/logcli/detected"
2021
"github.com/grafana/loki/v3/pkg/logcli/index"
2122
"github.com/grafana/loki/v3/pkg/logcli/labelquery"
@@ -315,6 +316,40 @@ The query is limited to processing 1000 lines per subquery; use --line-limit to
315316
`)
316317

317318
detectedFieldsQuery = newDetectedFieldsQuery(detectedFieldsCmd)
319+
320+
deleteCmd = app.Command("delete", "Manage log deletion requests.")
321+
322+
deleteCreateCmd = deleteCmd.Command("create", `Create a new log deletion request.
323+
324+
The "delete create" command creates a new log deletion request for the specified query and time range.
325+
326+
Example:
327+
328+
logcli delete create '{job="app"}' --from="2023-01-01T00:00:00Z" --to="2023-01-02T00:00:00Z"
329+
`)
330+
deleteCreateQuery = newDeleteCreateQuery(deleteCreateCmd)
331+
332+
deleteListCmd = deleteCmd.Command("list", `List existing log deletion requests.
333+
334+
The "delete list" command lists all existing log deletion requests for the tenant.
335+
336+
Example:
337+
338+
logcli delete list
339+
logcli delete list --output=json
340+
`)
341+
deleteListQuery = newDeleteListQuery(deleteListCmd)
342+
343+
deleteCancelCmd = deleteCmd.Command("cancel", `Cancel a log deletion request.
344+
345+
The "delete cancel" command cancels an existing log deletion request by ID.
346+
347+
Example:
348+
349+
logcli delete cancel --request-id="abc123"
350+
logcli delete cancel --request-id="abc123" --force
351+
`)
352+
deleteCancelQuery = newDeleteCancelQuery(deleteCancelCmd)
318353
)
319354

320355
func main() {
@@ -471,6 +506,24 @@ func main() {
471506
}
472507
case detectedFieldsCmd.FullCommand():
473508
detectedFieldsQuery.Do(queryClient, *outputMode)
509+
case deleteCreateCmd.FullCommand():
510+
if err := deleteCreateQuery.CreateQuery(queryClient); err != nil {
511+
log.Fatalf("Error creating delete request: %s", err)
512+
}
513+
case deleteListCmd.FullCommand():
514+
if *outputMode == "jsonl" {
515+
if err := deleteListQuery.ListQueryJSON(queryClient); err != nil {
516+
log.Fatalf("Error listing delete requests: %s", err)
517+
}
518+
} else {
519+
if err := deleteListQuery.ListQuery(queryClient); err != nil {
520+
log.Fatalf("Error listing delete requests: %s", err)
521+
}
522+
}
523+
case deleteCancelCmd.FullCommand():
524+
if err := deleteCancelQuery.CancelQuery(queryClient, deleteCancelQuery.RequestID, deleteCancelQuery.Force); err != nil {
525+
log.Fatalf("Error cancelling delete request: %s", err)
526+
}
474527
}
475528
}
476529

@@ -781,3 +834,54 @@ func newDetectedFieldsQuery(cmd *kingpin.CmdClause) *detected.FieldsQuery {
781834

782835
return q
783836
}
837+
838+
func newDeleteCreateQuery(cmd *kingpin.CmdClause) *delete.Query {
839+
var from, to string
840+
var since time.Duration
841+
842+
q := &delete.Query{}
843+
844+
cmd.Action(func(_ *kingpin.ParseContext) error {
845+
defaultEnd := time.Now()
846+
defaultStart := defaultEnd.Add(-since)
847+
848+
q.Start = mustParse(from, defaultStart)
849+
q.End = mustParse(to, defaultEnd)
850+
q.Quiet = *quiet
851+
852+
return nil
853+
})
854+
855+
cmd.Arg("query", "LogQL query to match log lines for deletion (e.g. '{job=\"app\"}')").Required().StringVar(&q.QueryString)
856+
cmd.Flag("since", "Lookback window.").Default("1h").DurationVar(&since)
857+
cmd.Flag("from", "Start time for deletion (inclusive)").StringVar(&from)
858+
cmd.Flag("to", "End time for deletion (exclusive)").StringVar(&to)
859+
cmd.Flag("max-interval", "Maximum time interval for delete request").StringVar(&q.MaxInterval)
860+
861+
return q
862+
}
863+
864+
func newDeleteListQuery(cmd *kingpin.CmdClause) *delete.Query {
865+
q := &delete.Query{}
866+
867+
cmd.Action(func(_ *kingpin.ParseContext) error {
868+
q.Quiet = *quiet
869+
return nil
870+
})
871+
872+
return q
873+
}
874+
875+
func newDeleteCancelQuery(cmd *kingpin.CmdClause) *delete.Query {
876+
q := &delete.Query{}
877+
878+
cmd.Action(func(_ *kingpin.ParseContext) error {
879+
q.Quiet = *quiet
880+
return nil
881+
})
882+
883+
cmd.Flag("request-id", "ID of the delete request to cancel").Required().StringVar(&q.RequestID)
884+
cmd.Flag("force", "Force cancellation of partially completed request").BoolVar(&q.Force)
885+
886+
return q
887+
}

0 commit comments

Comments
 (0)