Repository: incubator-htrace Updated Branches: refs/heads/master d1c65bf89 -> 3e6288491
HTRACE-30. Add writeSpan REST verb to htraced (cmccabe) Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/3e628849 Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/3e628849 Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/3e628849 Branch: refs/heads/master Commit: 3e62884919812eda64c69f7bdc7dd2685943d0f7 Parents: d1c65bf Author: Colin P. Mccabe <[email protected]> Authored: Sun Jan 4 11:51:45 2015 -0800 Committer: Colin P. Mccabe <[email protected]> Committed: Sun Jan 4 22:42:02 2015 -0800 ---------------------------------------------------------------------- .../src/go/src/org/apache/htrace/common/span.go | 15 +++++++-- .../src/go/src/org/apache/htrace/htrace/cmd.go | 33 ++++++++++++++++---- .../go/src/org/apache/htrace/htraced/rest.go | 31 ++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/3e628849/htrace-core/src/go/src/org/apache/htrace/common/span.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/common/span.go b/htrace-core/src/go/src/org/apache/htrace/common/span.go index 540ba12..4efc101 100644 --- a/htrace-core/src/go/src/org/apache/htrace/common/span.go +++ b/htrace-core/src/go/src/org/apache/htrace/common/span.go @@ -21,6 +21,7 @@ package common import ( "encoding/json" + "errors" "fmt" "strconv" ) @@ -56,8 +57,16 @@ func (id SpanId) MarshalJSON() ([]byte, error) { return []byte(`"` + fmt.Sprintf("%016x", uint64(id)) + `"`), nil } -func (id *SpanId) UnMarshalJSON(b []byte) error { - v, err := strconv.ParseUint(string(b), 16, 64) +const DOUBLE_QUOTE = 0x22 + +func (id *SpanId) UnmarshalJSON(b []byte) error { + if b[0] != DOUBLE_QUOTE { + return errors.New("Expected spanID to start with a string quote.") + } + if b[len(b)-1] != DOUBLE_QUOTE { + return errors.New("Expected spanID to end with a string quote.") + } + v, err := strconv.ParseUint(string(b[1:len(b)-1]), 16, 64) if err != nil { return err } @@ -77,7 +86,7 @@ type SpanData struct { } type Span struct { - Id SpanId `json:"s,string"` + Id SpanId `json:"s"` SpanData } http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/3e628849/htrace-core/src/go/src/org/apache/htrace/htrace/cmd.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/htrace/cmd.go b/htrace-core/src/go/src/org/apache/htrace/htrace/cmd.go index 3b89c72..d3129e4 100644 --- a/htrace-core/src/go/src/org/apache/htrace/htrace/cmd.go +++ b/htrace-core/src/go/src/org/apache/htrace/htrace/cmd.go @@ -20,10 +20,12 @@ package main import ( + "bytes" "encoding/json" "errors" "fmt" "gopkg.in/alecthomas/kingpin.v1" + "io" "io/ioutil" "net/http" "org/apache/htrace/common" @@ -48,6 +50,8 @@ func main() { parentSpanId := findChildren.Flag("id", "Span ID to print children for, as a signed decimal 64-bit "+ "number").Required().Int64() childLim := findChildren.Flag("lim", "Maximum number of child IDs to print.").Default("20").Int() + writeSpans := app.Command("writeSpans", "Write spans to the server in JSON form.") + spanJson := writeSpans.Flag("json", "The JSON span data to write to the server.").Required().String() // Handle operation switch kingpin.MustParse(app.Parse(os.Args[1:])) { @@ -59,6 +63,8 @@ func main() { os.Exit(doFindSpan((*addr).String(), *findSpanId)) case findChildren.FullCommand(): os.Exit(doFindChildren((*addr).String(), *parentSpanId, *childLim)) + case writeSpans.FullCommand(): + os.Exit(doWriteSpans(addr.String(), *spanJson)) } app.UsageErrorf(os.Stderr, "You must supply a command to run.") @@ -70,9 +76,9 @@ func printVersion() int { return 0 } -// Print information retrieved from an htraced server via /serverInfo +// Print information retrieved from an htraced server via /server/info func printServerInfo(restAddr string) int { - buf, err := makeRestRequest(restAddr, "serverInfo") + buf, err := makeGetRequest(restAddr, "server/info") if err != nil { fmt.Printf("%s\n", err.Error()) return 1 @@ -90,7 +96,7 @@ func printServerInfo(restAddr string) int { // Print information about a trace span. func doFindSpan(restAddr string, sid int64) int { - buf, err := makeRestRequest(restAddr, fmt.Sprintf("findSid?sid=%016x", sid)) + buf, err := makeGetRequest(restAddr, fmt.Sprintf("%016x", sid)) if err != nil { fmt.Printf("%s\n", err.Error()) return 1 @@ -111,9 +117,19 @@ func doFindSpan(restAddr string, sid int64) int { return 0 } +func doWriteSpans(restAddr string, spanJson string) int { + body := []byte(spanJson) + _, err := makeRestRequest("POST", restAddr, "writeSpans", bytes.NewReader(body)) + if err != nil { + fmt.Printf("%s\n", err.Error()) + return 1 + } + return 0 +} + // Find information about the children of a span. func doFindChildren(restAddr string, sid int64, lim int) int { - buf, err := makeRestRequest(restAddr, fmt.Sprintf("findChildren?sid=%016x&lim=%d", sid, lim)) + buf, err := makeGetRequest(restAddr, fmt.Sprintf("%016x/children&lim=%d", sid, lim)) if err != nil { fmt.Printf("%s\n", err.Error()) return 1 @@ -134,10 +150,15 @@ func doFindChildren(restAddr string, sid int64, lim int) int { return 0 } +func makeGetRequest(restAddr string, reqName string) ([]byte, error) { + return makeRestRequest("GET", restAddr, reqName, nil) +} + // Print information retrieved from an htraced server via /serverInfo -func makeRestRequest(restAddr string, reqName string) ([]byte, error) { +func makeRestRequest(reqType string, restAddr string, reqName string, + reqBody io.Reader) ([]byte, error) { url := fmt.Sprintf("http://%s/%s", restAddr, reqName) - req, err := http.NewRequest("GET", url, nil) + req, err := http.NewRequest(reqType, url, reqBody) client := &http.Client{} resp, err := client.Do(req) if err != nil { http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/3e628849/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go ---------------------------------------------------------------------- diff --git a/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go b/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go index ae28f8d..9f22de9 100644 --- a/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go +++ b/htrace-core/src/go/src/org/apache/htrace/htraced/rest.go @@ -22,6 +22,7 @@ package main import ( "encoding/json" "github.com/gorilla/mux" + "io" "log" "mime" "net/http" @@ -128,6 +129,33 @@ func (hand *findChildrenHandler) ServeHTTP(w http.ResponseWriter, req *http.Requ w.Write(jbytes) } +type writeSpansHandler struct { + dataStoreHandler +} + +func (hand *writeSpansHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + dec := json.NewDecoder(req.Body) + spans := make([]*common.Span, 0, 32) + for { + var span common.Span + err := dec.Decode(&span) + if err != nil { + if err != io.EOF { + w.WriteHeader(http.StatusBadRequest) + log.Printf("Error parsing spans: %s\n", err.Error()) + w.Write([]byte("Error parsing spans : " + err.Error())) + return + } + break + } + spans = append(spans, &span) + } + for spanIdx := range spans { + log.Printf("writing span %s\n", spans[spanIdx].ToJson()) + hand.store.WriteSpan(spans[spanIdx]) + } +} + type defaultServeHandler struct { } @@ -157,6 +185,9 @@ func startRestServer(cnf *conf.Config, store *dataStore) { r.Handle("/server/info", &serverInfoHandler{}).Methods("GET") + writeSpansH := &writeSpansHandler{dataStoreHandler: dataStoreHandler{store: store}} + r.Handle("/writeSpans", writeSpansH).Methods("POST") + span := r.PathPrefix("/span").Subrouter() findSidH := &findSidHandler{dataStoreHandler: dataStoreHandler{store: store}} span.Handle("/{id}", findSidH).Methods("GET")
