2020-04-05 07:51:16 +00:00
package command
import (
"context"
"fmt"
"io"
2020-08-29 02:43:04 +00:00
"path/filepath"
"strings"
2020-04-28 06:49:46 +00:00
"time"
2020-04-05 07:51:16 +00:00
"github.com/chrislusf/seaweedfs/weed/pb"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/util"
)
func init ( ) {
2021-01-13 02:48:01 +00:00
cmdFilerMetaTail . Run = runFilerMetaTail // break init cycle
2020-04-05 07:51:16 +00:00
}
2021-01-13 02:48:01 +00:00
var cmdFilerMetaTail = & Command {
UsageLine : "filer.meta.tail [-filer=localhost:8888] [-target=/]" ,
2020-04-05 07:51:16 +00:00
Short : "see recent changes on a filer" ,
Long : ` See recent changes on a filer .
` ,
}
var (
2021-01-13 08:31:19 +00:00
tailFiler = cmdFilerMetaTail . Flag . String ( "filer" , "localhost:8888" , "filer hostname:port" )
tailTarget = cmdFilerMetaTail . Flag . String ( "pathPrefix" , "/" , "path to a folder or file, or common prefix for the folders or files on filer" )
tailStart = cmdFilerMetaTail . Flag . Duration ( "timeAgo" , 0 , "start time before now. \"300ms\", \"1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\"" )
tailPattern = cmdFilerMetaTail . Flag . String ( "pattern" , "" , "full path or just filename pattern, ex: \"/home/?opher\", \"*.pdf\", see https://golang.org/pkg/path/filepath/#Match " )
2020-04-05 07:51:16 +00:00
)
2021-01-13 02:48:01 +00:00
func runFilerMetaTail ( cmd * Command , args [ ] string ) bool {
2020-04-05 07:51:16 +00:00
grpcDialOption := security . LoadClientTLS ( util . GetViper ( ) , "grpc.client" )
2020-08-29 02:43:04 +00:00
var filterFunc func ( dir , fname string ) bool
2021-01-13 08:31:19 +00:00
if * tailPattern != "" {
if strings . Contains ( * tailPattern , "/" ) {
println ( "watch path pattern" , * tailPattern )
2020-08-29 02:43:04 +00:00
filterFunc = func ( dir , fname string ) bool {
2021-01-13 08:31:19 +00:00
matched , err := filepath . Match ( * tailPattern , dir + "/" + fname )
2020-08-29 02:43:04 +00:00
if err != nil {
fmt . Printf ( "error: %v" , err )
}
return matched
}
} else {
2021-01-13 08:31:19 +00:00
println ( "watch file pattern" , * tailPattern )
2020-08-29 02:43:04 +00:00
filterFunc = func ( dir , fname string ) bool {
2021-01-13 08:31:19 +00:00
matched , err := filepath . Match ( * tailPattern , fname )
2020-08-29 02:43:04 +00:00
if err != nil {
fmt . Printf ( "error: %v" , err )
}
return matched
}
}
}
shouldPrint := func ( resp * filer_pb . SubscribeMetadataResponse ) bool {
if filterFunc == nil {
return true
}
if resp . EventNotification . OldEntry == nil && resp . EventNotification . NewEntry == nil {
return false
}
if resp . EventNotification . OldEntry != nil && filterFunc ( resp . Directory , resp . EventNotification . OldEntry . Name ) {
return true
}
if resp . EventNotification . NewEntry != nil && filterFunc ( resp . EventNotification . NewParentPath , resp . EventNotification . NewEntry . Name ) {
return true
}
return false
}
2021-01-11 10:08:26 +00:00
eachEntryFunc := func ( resp * filer_pb . SubscribeMetadataResponse ) error {
2021-01-11 08:03:13 +00:00
fmt . Printf ( "dir:%s %+v\n" , resp . Directory , resp . EventNotification )
2021-01-11 10:08:26 +00:00
return nil
2021-01-11 08:03:13 +00:00
}
2021-01-13 08:31:19 +00:00
tailErr := pb . WithFilerClient ( * tailFiler , grpcDialOption , func ( client filer_pb . SeaweedFilerClient ) error {
2020-04-05 07:51:16 +00:00
2020-09-09 18:21:23 +00:00
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
stream , err := client . SubscribeMetadata ( ctx , & filer_pb . SubscribeMetadataRequest {
2021-01-13 08:31:19 +00:00
ClientName : "tail" ,
PathPrefix : * tailTarget ,
SinceNs : time . Now ( ) . Add ( - * tailStart ) . UnixNano ( ) ,
2020-04-05 07:51:16 +00:00
} )
if err != nil {
return fmt . Errorf ( "listen: %v" , err )
}
for {
resp , listenErr := stream . Recv ( )
if listenErr == io . EOF {
return nil
}
if listenErr != nil {
return listenErr
}
2020-08-29 02:43:04 +00:00
if ! shouldPrint ( resp ) {
continue
}
2021-01-11 10:08:26 +00:00
if err = eachEntryFunc ( resp ) ; err != nil {
return err
}
2020-04-05 07:51:16 +00:00
}
} )
2021-01-13 08:31:19 +00:00
if tailErr != nil {
fmt . Printf ( "tail %s: %v\n" , * tailFiler , tailErr )
2020-04-05 07:51:16 +00:00
}
return true
}