HTRACE-277: htraced: Add /server/conf endpoint to get server configuration (cmccabe)
diff --git a/htrace-htraced/go/src/org/apache/htrace/client/client.go b/htrace-htraced/go/src/org/apache/htrace/client/client.go
index dd3f8a3..dd8597d 100644
--- a/htrace-htraced/go/src/org/apache/htrace/client/client.go
+++ b/htrace-htraced/go/src/org/apache/htrace/client/client.go
@@ -82,6 +82,21 @@
return &stats, nil
}
+// Get the htraced server statistics.
+func (hcl *Client) GetServerConf() (map[string]string, error) {
+ buf, _, err := hcl.makeGetRequest("server/conf")
+ if err != nil {
+ return nil, err
+ }
+ cnf := make(map[string]string)
+ err = json.Unmarshal(buf, &cnf)
+ if err != nil {
+ return nil, errors.New(fmt.Sprintf("Error: error unmarshalling response "+
+ "body %s: %s", string(buf), err.Error()))
+ }
+ return cnf, nil
+}
+
// Get information about a trace span. Returns nil, nil if the span was not found.
func (hcl *Client) FindSpan(sid common.SpanId) (*common.Span, error) {
buf, rc, err := hcl.makeGetRequest(fmt.Sprintf("span/%s", sid.String()))
diff --git a/htrace-htraced/go/src/org/apache/htrace/conf/config.go b/htrace-htraced/go/src/org/apache/htrace/conf/config.go
index 76af7a6..d038723 100644
--- a/htrace-htraced/go/src/org/apache/htrace/conf/config.go
+++ b/htrace-htraced/go/src/org/apache/htrace/conf/config.go
@@ -266,3 +266,15 @@
}
return ncnf
}
+
+// Export the configuration as a map
+func (cnf *Config) Export() map[string]string {
+ m := make(map[string]string)
+ for k, v := range cnf.defaults {
+ m[k] = v
+ }
+ for k, v := range cnf.settings {
+ m[k] = v
+ }
+ return m
+}
diff --git a/htrace-htraced/go/src/org/apache/htrace/htrace/cmd.go b/htrace-htraced/go/src/org/apache/htrace/htrace/cmd.go
index b5549c5..f6972bb 100644
--- a/htrace-htraced/go/src/org/apache/htrace/htrace/cmd.go
+++ b/htrace-htraced/go/src/org/apache/htrace/htrace/cmd.go
@@ -65,6 +65,7 @@
serverInfo := app.Command("serverInfo", "Print information retrieved from an htraced server.")
serverStats := app.Command("serverStats", "Print statistics retrieved from the htraced server.")
serverStatsJson := serverStats.Flag("json", "Display statistics as raw JSON.").Default("false").Bool()
+ serverConf := app.Command("serverConf", "Print the server configuration retrieved from the htraced server.")
findSpan := app.Command("findSpan", "Print information about a trace span with a given ID.")
findSpanId := findSpan.Arg("id", "Span ID to find. Example: be305e54-4534-2110-a0b2-e06b9effe112").Required().String()
findChildren := app.Command("findChildren", "Print out the span IDs that are children of a given span ID.")
@@ -131,6 +132,8 @@
} else {
os.Exit(printServerStats(hcl))
}
+ case serverConf.FullCommand():
+ os.Exit(printServerConfJson(hcl))
case findSpan.FullCommand():
var id *common.SpanId
id.FromString(*findSpanId)
@@ -221,6 +224,22 @@
return EXIT_SUCCESS
}
+// Print information retrieved from an htraced server via /server/conf as JSON
+func printServerConfJson(hcl *htrace.Client) int {
+ cnf, err := hcl.GetServerConf()
+ if err != nil {
+ fmt.Println(err.Error())
+ return EXIT_FAILURE
+ }
+ buf, err := json.MarshalIndent(cnf, "", " ")
+ if err != nil {
+ fmt.Printf("Error marshalling server conf: %s", err.Error())
+ return EXIT_FAILURE
+ }
+ fmt.Printf("%s\n", string(buf))
+ return EXIT_SUCCESS
+}
+
// Print information about a trace span.
func doFindSpan(hcl *htrace.Client, sid common.SpanId) int {
span, err := hcl.FindSpan(sid)
diff --git a/htrace-htraced/go/src/org/apache/htrace/htraced/client_test.go b/htrace-htraced/go/src/org/apache/htrace/htraced/client_test.go
index 02a00f3..540e688 100644
--- a/htrace-htraced/go/src/org/apache/htrace/htraced/client_test.go
+++ b/htrace-htraced/go/src/org/apache/htrace/htraced/client_test.go
@@ -204,3 +204,32 @@
t.Fatalf("got dump error %s\n", dumpErr.Error())
}
}
+
+const EXAMPLE_CONF_KEY = "example.conf.key"
+const EXAMPLE_CONF_VALUE = "foo.bar.baz"
+
+func TestClientGetServerConf(t *testing.T) {
+ htraceBld := &MiniHTracedBuilder{Name: "TestClientGetServerConf",
+ Cnf: map[string]string {
+ EXAMPLE_CONF_KEY: EXAMPLE_CONF_VALUE,
+ },
+ DataDirs: make([]string, 2)}
+ ht, err := htraceBld.Build()
+ if err != nil {
+ t.Fatalf("failed to create datastore: %s", err.Error())
+ }
+ defer ht.Close()
+ var hcl *htrace.Client
+ hcl, err = htrace.NewClient(ht.ClientConf())
+ if err != nil {
+ t.Fatalf("failed to create client: %s", err.Error())
+ }
+ serverCnf, err2 := hcl.GetServerConf()
+ if err2 != nil {
+ t.Fatalf("failed to call GetServerConf: %s", err2.Error())
+ }
+ if serverCnf[EXAMPLE_CONF_KEY] != EXAMPLE_CONF_VALUE {
+ t.Fatalf("unexpected value for %s: %s",
+ EXAMPLE_CONF_KEY, EXAMPLE_CONF_VALUE)
+ }
+}
diff --git a/htrace-htraced/go/src/org/apache/htrace/htraced/rest.go b/htrace-htraced/go/src/org/apache/htrace/htraced/rest.go
index c038e59..16c3a75 100644
--- a/htrace-htraced/go/src/org/apache/htrace/htraced/rest.go
+++ b/htrace-htraced/go/src/org/apache/htrace/htraced/rest.go
@@ -88,6 +88,25 @@
w.Write(buf)
}
+type serverConfHandler struct {
+ cnf *conf.Config
+ lg *common.Logger
+}
+
+func (hand *serverConfHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ setResponseHeaders(w.Header())
+ hand.lg.Debugf("serverConfHandler\n")
+ cnfMap := hand.cnf.Export()
+ buf, err := json.Marshal(&cnfMap)
+ if err != nil {
+ writeError(hand.lg, w, http.StatusInternalServerError,
+ fmt.Sprintf("error marshalling serverConf: %s\n", err.Error()))
+ return
+ }
+ hand.lg.Debugf("Returned server configuration %s\n", string(buf))
+ w.Write(buf)
+}
+
type dataStoreHandler struct {
lg *common.Logger
store *dataStore
@@ -295,6 +314,9 @@
store: store, lg: rsv.lg}}
r.Handle("/server/stats", serverStatsH).Methods("GET")
+ serverConfH := &serverConfHandler{cnf: cnf, lg: rsv.lg}
+ r.Handle("/server/conf", serverConfH).Methods("GET")
+
writeSpansH := &writeSpansHandler{dataStoreHandler: dataStoreHandler{
store: store, lg: rsv.lg}}
r.Handle("/writeSpans", writeSpansH).Methods("POST")