Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
89 lines (75 sloc) 2.25 KB
package main
// MAKE SURE TO SET export GOMAXPROCS=16 in your environment before running
import "fmt"
import "flag"
import "time"
import "os"
import "regexp"
// import "reflect"
import "github.com/fzzy/radix/redis"
func fetchAllKeys(hostame string, port int, database int) []string {
c, err := redis.DialTimeout("tcp", fmt.Sprintf("%s:%d", hostname, port), time.Duration(300)*time.Second)
errHndlr(err)
keys := c.Cmd("SELECT", database)
keys = c.Cmd("KEYS", "*")
//fmt.Println("type:", reflect.TypeOf(keys))
j := keys.Elems
redis_keys := make([]string, len(j), len(j))
for i := 0; i < len(j); i++ {
redis_keys[i] = fmt.Sprintf("%s", j[i])
}
return redis_keys
}
func errHndlr(err error) {
if err != nil {
fmt.Println("error:", err)
os.Exit(1)
}
}
func worker(id int, jobs <-chan string, results chan<- string, hostame string, port int, database int) {
re := regexp.MustCompile("serializedlength:([0-9]+)")
c, err := redis.DialTimeout("tcp", fmt.Sprintf("%s:%d", hostname, port), time.Duration(3)*time.Second)
errHndlr(err)
for j := range jobs {
errHndlr(err)
k := c.Cmd("SELECT", database)
k = c.Cmd("DEBUG", "OBJECT", j)
match := re.FindStringSubmatch(fmt.Sprintf("%s", k))
if len(match) != 0 {
fmt.Printf("%s:%s:%d:%d:%s\n", match[1], hostname, port, database, j)
}
results <- "OK"
}
c.Close()
}
var hostname string
var port int
var concurrent int
var database int
func init() {
flag.StringVar(&hostname, "hostname", "localhost", "hostname or ip to scan")
flag.IntVar(&port, "port", 6379, "port to try to connect to")
flag.IntVar(&concurrent, "concurrent", 10, "number of workers to run")
flag.IntVar(&database, "database", 0, "Redis database to use. DB 0 is the default")
flag.Parse()
}
func main() {
keys := fetchAllKeys(hostname, port, database)
// In order to use our pool of workers we need to send
// them work and collect their results. We make 2
// channels for this.
jobs := make(chan string, len(keys))
results := make(chan string, len(keys))
for w := 0; w <= concurrent; w++ {
go worker(w, jobs, results, hostname, port, database)
}
for j := 0; j <= len(keys)-1; j++ {
jobs <- keys[j]
}
close(jobs)
// Finally we collect all the results of the work.
for a := 0; a <= len(keys)-1; a++ {
<-results
}
os.Exit(0)
}