122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"github.com/golang/protobuf/jsonpb"
|
|
"github.com/golang/protobuf/proto"
|
|
"golang.org/x/net/context"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/channelz/grpc_channelz_v1"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var marshaler = jsonpb.Marshaler{EmitDefaults: true, Indent: " "}
|
|
var unmarshaler = jsonpb.Unmarshaler{}
|
|
|
|
func printHelper(w http.ResponseWriter, pb proto.Message) {
|
|
w.WriteHeader(http.StatusOK)
|
|
json, _ := marshaler.MarshalToString(pb)
|
|
fmt.Fprintf(w, "%s", json)
|
|
}
|
|
|
|
func errorHelper(w http.ResponseWriter, errstr string) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
fmt.Fprintf(w, "%s", errstr)
|
|
}
|
|
|
|
func main() {
|
|
var serverAddr = flag.String("serverAddr", "", "the target server address")
|
|
var port = flag.Int("port", 8080, "local port")
|
|
flag.Parse()
|
|
|
|
fmt.Println(os.Stdout, "Address: %s", *serverAddr)
|
|
var opts []grpc.DialOption
|
|
opts = append(opts, grpc.WithInsecure())
|
|
conn, err := grpc.Dial(*serverAddr, opts...)
|
|
defer conn.Close()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to connect to %s\n", serverAddr)
|
|
}
|
|
client := grpc_channelz_v1.NewChannelzClient(conn)
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/grpcz_internal", func(w http.ResponseWriter, r *http.Request) {
|
|
q := r.URL.Query()
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
json := strings.NewReader(q["request"][0])
|
|
switch method := q["full_method_name"][0]; method {
|
|
case "grpc.channelz.v1.Channelz/GetServers":
|
|
req := grpc_channelz_v1.GetServersRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetServers(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
case "grpc.channelz.v1.Channelz/GetServerSockets":
|
|
req := grpc_channelz_v1.GetServerSocketsRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetServerSockets(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
case "grpc.channelz.v1.Channelz/GetTopChannels":
|
|
req := grpc_channelz_v1.GetTopChannelsRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetTopChannels(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
case "grpc.channelz.v1.Channelz/GetSubchannel":
|
|
req := grpc_channelz_v1.GetSubchannelRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetSubchannel(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
case "grpc.channelz.v1.Channelz/GetChannel":
|
|
req := grpc_channelz_v1.GetSubchannelRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetSubchannel(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
case "grpc.channelz.v1.Channelz/GetSocket":
|
|
req := grpc_channelz_v1.GetSocketRequest{}
|
|
unmarshaler.Unmarshal(json, &req)
|
|
response, err := client.GetSocket(ctx, &req)
|
|
if err != nil {
|
|
errorHelper(w, err.Error())
|
|
return
|
|
}
|
|
printHelper(w, response)
|
|
default:
|
|
errorHelper(w, "Invalid method")
|
|
}
|
|
})
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
if (strings.HasSuffix(r.URL.Path, ".css") || strings.HasSuffix(r.URL.Path, ".js")) {
|
|
http.ServeFile(w, r, r.URL.Path[1:])
|
|
} else {
|
|
http.ServeFile(w, r, "dist_channelz/index.html")
|
|
}
|
|
})
|
|
fmt.Printf("zpages now serving at: http://localhost:%d for %s\n", *port, *serverAddr)
|
|
|
|
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), mux))
|
|
}
|