@@ -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
320355func 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