Skip to content

Commit

Permalink
Simplify Implementation of Endpoint /info + Expose ALL Results from I…
Browse files Browse the repository at this point in the history
…NFO Command (#21)

- Use map instead of struct to create the JSON, so it's much more flexible and makes the implementation simpler.
- Allow exposing ALL results from Redis INFO command.
  • Loading branch information
XD-DENG authored Dec 26, 2019
1 parent 07b060a commit 3a3fd91
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 119 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/rediseen_integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,12 @@ jobs:
check_by_status_code http://localhost:9000/info 200
check_by_status_code http://localhost:9000/info/server 200
check_by_status_code http://localhost:9000/info/clients 200
check_by_status_code http://localhost:9000/info/cluster 200
check_by_status_code http://localhost:9000/info/memory 200
check_by_status_code http://localhost:9000/info/cpu 200
check_by_status_code http://localhost:9000/info/SERVER 200
check_by_status_code http://localhost:9000/info/CLIENTS 200
check_by_status_code http://localhost:9000/info/MEMORY 200
check_by_status_code http://localhost:9000/info/CPU 200
check_by_status_code http://localhost:9000/info/invalidSection 400
./rediseen stop
Expand All @@ -151,5 +155,6 @@ jobs:
check_by_status_code http://localhost:9000/0 401
check_by_status_code http://localhost:9000/info 401
check_by_status_code http://localhost:9000/info/server 401
./rediseen stop
65 changes: 17 additions & 48 deletions conn/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package conn
import (
"encoding/json"
"errors"
"fmt"
"github.com/go-redis/redis"
"net/http"
"os"
Expand Down Expand Up @@ -147,68 +148,36 @@ func (client *ExtendedClient) Retrieve(res http.ResponseWriter, key string, inde
res.Write(js)
}

func (client *ExtendedClient) RedisInfo(section string) (types.Info, error) {
// RedisInfo takes the results of Redis INFO command, then return the result as JSON ([]byte format from json.Marshal)
func (client *ExtendedClient) RedisInfo(section string) ([]byte, error) {
var infoResult string
var err error
if section == "" {
infoResult, err = client.RedisClient.Info().Result()
infoResult, err = client.RedisClient.Info("all").Result()
} else {
infoResult, err = client.RedisClient.Info(section).Result()
if infoResult == "" {
return []byte{}, fmt.Errorf("invalid section `%s` is given. Check /info for supported sections", section)
}
}
if err != nil {
return types.Info{}, err
return []byte{}, err
}

mapResult := make(map[string]string)
mapResult := make(map[string]map[string]string)
var sectionName string
for _, kv := range strings.Split(infoResult, "\n") {
if len(kv) > 0 && string(kv[0]) == "#" {
sectionName = strings.Trim(kv, "\r# ")
mapResult[sectionName] = make(map[string]string)
}
values := strings.Split(kv, ":")
if len(values) != 2 {
continue
}
mapResult[values[0]] = strings.TrimSpace(values[1])
}

var result types.Info

result.Server = types.InfoServer{
RedisVersion: mapResult["redis_version"],
RedisBuildId: mapResult["redis_build_id"],
RedisMode: mapResult["redis_mode"],
Os: mapResult["os"],
ArchBits: mapResult["arch_bits"],
GccVersion: mapResult["gcc_version"],
ProcessId: mapResult["process_id"],
RunId: mapResult["run_id"],
TcpPort: mapResult["tcp_port"],
UptimeInSeconds: mapResult["uptime_in_seconds"],
UptimeInDays: mapResult["uptime_in_days"],
Hz: mapResult["hz"],
ConfiguredHz: mapResult["configured_hz"],
LruClock: mapResult["lru_clock"],
Executable: mapResult["executable"],
ConfigFile: mapResult["config_file"],
}

result.Clients = types.InfoClients{
ConnectedClients: mapResult["connected_clients"],
BlockedClients: mapResult["blocked_clients"],
mapResult[sectionName][values[0]] = strings.TrimSpace(values[1])
}

result.Replication = types.InfoReplication{
Role: mapResult["role"],
ConnectedSlaves: mapResult["connected_slaves"],
MasterReplId: mapResult["master_replid"],
MasterReplId2: mapResult["master_replid2"],
}

result.CPU = types.InfoCpu{
UsedCpuSys: mapResult["used_cpu_sys"],
UsedCpuUser: mapResult["used_cpu_user"],
UsedCpuSysChildren: mapResult["used_cpu_sys_children"],
UsedCpuUserChildren: mapResult["used_cpu_user_children"],
}

result.Cluster = types.InfoCluster{ClusterEnabled: mapResult["cluster_enabled"]}

return result, nil
jsonResult, _ := json.Marshal(mapResult)
return jsonResult, nil
}
24 changes: 5 additions & 19 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,28 +189,14 @@ func (c *service) ServeHTTP(res http.ResponseWriter, req *http.Request) {
client.Init(0)
defer client.RedisClient.Close()

info, err := client.RedisInfo(section)
js, err := client.RedisInfo(section)
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
js, _ = json.Marshal(types.ErrorType{Error: "Exception while getting Redis Info. Details: " + err.Error()})
} else {
switch section {
case "":
js, _ = json.Marshal(info)
case "server":
js, _ = json.Marshal(info.Server)
case "clients":
js, _ = json.Marshal(info.Clients)
case "replication":
js, _ = json.Marshal(info.Replication)
case "cpu":
js, _ = json.Marshal(info.CPU)
case "cluster":
js, _ = json.Marshal(info.Cluster)
default:
if strings.Contains(err.Error(), "invalid section") {
res.WriteHeader(http.StatusBadRequest)
js, _ = json.Marshal(types.ErrorType{Error: fmt.Sprintf("invalid section `%s` is given. Check /info for supported sections.", section)})
} else {
res.WriteHeader(http.StatusInternalServerError)
}
js, _ = json.Marshal(types.ErrorType{Error: "Exception while getting Redis Info. Details: " + err.Error()})
}
res.Write(js)
return
Expand Down
50 changes: 0 additions & 50 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,53 +23,3 @@ type KeyListType struct {
Total int `json:"total"`
Keys []KeyInfoType `json:"keys"`
}

type InfoServer struct {
RedisVersion string `json:"redis_version"`
RedisBuildId string `json:"redis_build_id"`
RedisMode string `json:"redis_mode"`
Os string `json:"os"`
ArchBits string `json:"arch_bits"`
GccVersion string `json:"gcc_version"`
ProcessId string `json:"process_id"`
RunId string `json:"run_id"`
TcpPort string `json:"tcp_port"`
UptimeInSeconds string `json:"uptime_in_seconds"`
UptimeInDays string `json:"uptime_in_days"`
Hz string `json:"hz"`
ConfiguredHz string `json:"configured_hz"`
LruClock string `json:"lru_clock"`
Executable string `json:"executable"`
ConfigFile string `json:"config_file"`
}

type InfoClients struct {
ConnectedClients string `json:"connected_clients"`
BlockedClients string `json:"blocked_clients"`
}

type InfoReplication struct {
Role string `json:"role"`
ConnectedSlaves string `json:"connected_slaves"`
MasterReplId string `json:"master_replid"`
MasterReplId2 string `json:"master_replid2"`
}

type InfoCpu struct {
UsedCpuSys string `json:"used_cpu_sys"`
UsedCpuUser string `json:"used_cpu_user"`
UsedCpuSysChildren string `json:"used_cpu_sys_children"`
UsedCpuUserChildren string `json:"used_cpu_user_children"`
}

type InfoCluster struct {
ClusterEnabled string `json:"cluster_enabled"`
}

type Info struct {
Server InfoServer
Clients InfoClients
Replication InfoReplication
CPU InfoCpu
Cluster InfoCluster
}
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package main

const rediseenVersion = "2.0.1-dev"
const rediseenVersion = "2.1.0"

0 comments on commit 3a3fd91

Please sign in to comment.