github.com/hdt3213/godis@v1.2.9/database/systemcmd.go (about) 1 package database 2 3 import ( 4 "fmt" 5 "github.com/hdt3213/godis/config" 6 "github.com/hdt3213/godis/interface/redis" 7 "github.com/hdt3213/godis/redis/protocol" 8 "github.com/hdt3213/godis/tcp" 9 "os" 10 "runtime" 11 "strings" 12 "time" 13 ) 14 15 // Ping the server 16 func Ping(c redis.Connection, args [][]byte) redis.Reply { 17 if len(args) == 0 { 18 return &protocol.PongReply{} 19 } else if len(args) == 1 { 20 return protocol.MakeStatusReply(string(args[0])) 21 } else { 22 return protocol.MakeErrReply("ERR wrong number of arguments for 'ping' command") 23 } 24 } 25 26 // Info the information of the godis server returned by the INFO command 27 func Info(db *Server, args [][]byte) redis.Reply { 28 if len(args) == 0 { 29 infoCommandList := [...]string{"server", "client", "cluster", "keyspace"} 30 var allSection []byte 31 for _, s := range infoCommandList { 32 allSection = append(allSection, GenGodisInfoString(s, db)...) 33 } 34 return protocol.MakeBulkReply(allSection) 35 } else if len(args) == 1 { 36 section := strings.ToLower(string(args[0])) 37 switch section { 38 case "server": 39 reply := GenGodisInfoString("server", db) 40 return protocol.MakeBulkReply(reply) 41 case "client": 42 return protocol.MakeBulkReply(GenGodisInfoString("client", db)) 43 case "cluster": 44 return protocol.MakeBulkReply(GenGodisInfoString("cluster", db)) 45 case "keyspace": 46 return protocol.MakeBulkReply(GenGodisInfoString("keyspace", db)) 47 default: 48 return protocol.MakeErrReply("Invalid section for 'info' command") 49 } 50 } 51 return protocol.MakeArgNumErrReply("info") 52 } 53 54 // Auth validate client's password 55 func Auth(c redis.Connection, args [][]byte) redis.Reply { 56 if len(args) != 1 { 57 return protocol.MakeErrReply("ERR wrong number of arguments for 'auth' command") 58 } 59 if config.Properties.RequirePass == "" { 60 return protocol.MakeErrReply("ERR Client sent AUTH, but no password is set") 61 } 62 passwd := string(args[0]) 63 c.SetPassword(passwd) 64 if config.Properties.RequirePass != passwd { 65 return protocol.MakeErrReply("ERR invalid password") 66 } 67 return &protocol.OkReply{} 68 } 69 70 func isAuthenticated(c redis.Connection) bool { 71 if config.Properties.RequirePass == "" { 72 return true 73 } 74 return c.GetPassword() == config.Properties.RequirePass 75 } 76 77 func GenGodisInfoString(section string, db *Server) []byte { 78 startUpTimeFromNow := getGodisRuninngTime() 79 switch section { 80 case "server": 81 s := fmt.Sprintf("# Server\r\n"+ 82 "godis_version:%s\r\n"+ 83 //"godis_git_sha1:%s\r\n"+ 84 //"godis_git_dirty:%d\r\n"+ 85 //"godis_build_id:%s\r\n"+ 86 "godis_mode:%s\r\n"+ 87 "os:%s %s\r\n"+ 88 "arch_bits:%d\r\n"+ 89 //"multiplexing_api:%s\r\n"+ 90 "go_version:%s\r\n"+ 91 "process_id:%d\r\n"+ 92 "run_id:%s\r\n"+ 93 "tcp_port:%d\r\n"+ 94 "uptime_in_seconds:%d\r\n"+ 95 "uptime_in_days:%d\r\n"+ 96 //"hz:%d\r\n"+ 97 //"lru_clock:%d\r\n"+ 98 "config_file:%s\r\n", 99 godisVersion, 100 //TODO, 101 //TODO, 102 //TODO, 103 getGodisRunningMode(), 104 runtime.GOOS, runtime.GOARCH, 105 32<<(^uint(0)>>63), 106 //TODO, 107 runtime.Version(), 108 os.Getpid(), 109 config.Properties.RunID, 110 config.Properties.Port, 111 startUpTimeFromNow, 112 startUpTimeFromNow/time.Duration(3600*24), 113 //TODO, 114 //TODO, 115 config.Properties.CfPath) 116 return []byte(s) 117 case "client": 118 s := fmt.Sprintf("# Clients\r\n"+ 119 "connected_clients:%d\r\n", 120 //"client_recent_max_input_buffer:%d\r\n"+ 121 //"client_recent_max_output_buffer:%d\r\n"+ 122 //"blocked_clients:%d\n", 123 tcp.ClientCounter, 124 //TODO, 125 //TODO, 126 //TODO, 127 ) 128 return []byte(s) 129 case "cluster": 130 if getGodisRunningMode() == config.ClusterMode { 131 s := fmt.Sprintf("# Cluster\r\n"+ 132 "cluster_enabled:%s\r\n", 133 "1", 134 ) 135 return []byte(s) 136 } else { 137 s := fmt.Sprintf("# Cluster\r\n"+ 138 "cluster_enabled:%s\r\n", 139 "0", 140 ) 141 return []byte(s) 142 } 143 case "keyspace": 144 dbCount := config.Properties.Databases 145 var serv []byte 146 for i := 0; i < dbCount; i++ { 147 keys, expiresKeys := db.GetDBSize(i) 148 if keys != 0 { 149 ttlSampleAverage := db.GetAvgTTL(i, 20) 150 serv = append(serv, getDbSize(i, keys, expiresKeys, ttlSampleAverage)...) 151 } 152 } 153 prefix := []byte("# Keyspace\r\n") 154 keyspaceInfo := append(prefix, serv...) 155 return keyspaceInfo 156 } 157 return []byte("") 158 } 159 160 // getGodisRunningMode return godis running mode 161 func getGodisRunningMode() string { 162 if config.Properties.ClusterEnabled == "yes" { 163 return config.ClusterMode 164 } else { 165 return config.StandaloneMode 166 } 167 } 168 169 // getGodisRuninngTime return the running time of godis 170 func getGodisRuninngTime() time.Duration { 171 return time.Since(config.EachTimeServerInfo.StartUpTime) / time.Second 172 } 173 174 func getDbSize(dbIndex, keys, expiresKeys int, ttl int64) []byte { 175 s := fmt.Sprintf("db%d:keys=%d,expires=%d,avg_ttl=%d\r\n", 176 dbIndex, keys, expiresKeys, ttl) 177 return []byte(s) 178 }