func loadPredicateData(pred *common.Predicate) (*predicateData, error) { p := predicateData{Predicate: pred} // Parse the input value given to make sure it matches up with the field // type. switch pred.Field { case common.SPAN_ID: // Span IDs are sent as hex strings. var id common.SpanId if err := id.FromString(pred.Val); err != nil { return nil, errors.New(fmt.Sprintf("Unable to parse span id '%s': %s", pred.Val, err.Error())) } p.key = id.Val() break case common.DESCRIPTION: // Any string is valid for a description. p.key = []byte(pred.Val) break case common.BEGIN_TIME, common.END_TIME, common.DURATION: // Parse a base-10 signed numeric field. v, err := strconv.ParseInt(pred.Val, 10, 64) if err != nil { return nil, errors.New(fmt.Sprintf("Unable to parse %s '%s': %s", pred.Field, pred.Val, err.Error())) } p.key = u64toSlice(s2u64(v)) break case common.TRACER_ID: // Any string is valid for a tracer ID. p.key = []byte(pred.Val) break default: return nil, errors.New(fmt.Sprintf("Unknown field %s", pred.Field)) } // Validate the predicate operation. switch pred.Op { case common.EQUALS, common.LESS_THAN_OR_EQUALS, common.GREATER_THAN_OR_EQUALS, common.GREATER_THAN: break case common.CONTAINS: if p.fieldIsNumeric() { return nil, errors.New(fmt.Sprintf("Can't use CONTAINS on a "+ "numeric field like '%s'", pred.Field)) } default: return nil, errors.New(fmt.Sprintf("Unknown predicate operation '%s'", pred.Op)) } return &p, nil }
func (hand *dataStoreHandler) parseSid(w http.ResponseWriter, str string) (common.SpanId, bool) { var id common.SpanId err := id.FromString(str) if err != nil { writeError(hand.lg, w, http.StatusBadRequest, fmt.Sprintf("Failed to parse span ID %s: %s", str, err.Error())) w.Write([]byte("Error parsing : " + err.Error())) return common.INVALID_SPAN_ID, false } return id, true }
func main() { // Load htraced configuration cnf := common.LoadApplicationConfig() // Parse argv app := kingpin.New(os.Args[0], USAGE) app.Flag("Dmy.key", "Set configuration key 'my.key' to 'my.value'. Replace 'my.key' "+ "with any key you want to set.").Default("my.value").String() addr := app.Flag("addr", "Server address.").String() verbose = app.Flag("verbose", "Verbose.").Default("false").Bool() version := app.Command("version", "Print the version of this program.") 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() 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.") parentSpanId := findChildren.Arg("id", "Span ID to print children for. Example: be305e54-4534-2110-a0b2-e06b9effe112"). Required().String() childLim := findChildren.Flag("lim", "Maximum number of child IDs to print.").Default("20").Int() loadFile := app.Command("loadFile", "Write whitespace-separated JSON spans from a file to the server.") loadFilePath := loadFile.Arg("path", "A file containing whitespace-separated span JSON.").Required().String() loadJson := app.Command("load", "Write JSON spans from the command-line to the server.") loadJsonArg := loadJson.Arg("json", "A JSON span to write to the server.").Required().String() dumpAll := app.Command("dumpAll", "Dump all spans from the htraced daemon.") dumpAllOutPath := dumpAll.Arg("path", "The path to dump the trace spans to.").Default("-").String() dumpAllLim := dumpAll.Flag("lim", "The number of spans to transfer from the server at once."). Default("100").Int() graph := app.Command("graph", "Visualize span JSON as a graph.") graphJsonFile := graph.Arg("input", "The JSON file to load").Required().String() graphDotFile := graph.Flag("output", "The path to write a GraphViz dotfile to. This file can be used as input to "+ "GraphViz, in order to generate a pretty picture. See graphviz.org for more "+ "information about generating pictures of graphs.").Default("-").String() query := app.Command("query", "Send a query to htraced.") queryLim := query.Flag("lim", "Maximum number of spans to retrieve.").Default("20").Int() queryArg := query.Arg("query", "The query string to send. Query strings have the format "+ "[TYPE] [OPERATOR] [CONST], joined by AND statements.").Required().String() rawQuery := app.Command("rawQuery", "Send a raw JSON query to htraced.") rawQueryArg := query.Arg("json", "The query JSON to send.").Required().String() cmd := kingpin.MustParse(app.Parse(os.Args[1:])) // Add the command-line settings into the configuration. if *addr != "" { cnf = cnf.Clone(conf.HTRACE_WEB_ADDRESS, *addr) } // Handle commands that don't require an HTrace client. switch cmd { case version.FullCommand(): os.Exit(printVersion()) case graph.FullCommand(): err := jsonSpanFileToDotFile(*graphJsonFile, *graphDotFile) if err != nil { fmt.Printf("graphing error: %s\n", err.Error()) os.Exit(EXIT_FAILURE) } os.Exit(EXIT_SUCCESS) } // Create HTrace client hcl, err := htrace.NewClient(cnf) if err != nil { fmt.Printf("Failed to create HTrace client: %s\n", err.Error()) os.Exit(EXIT_FAILURE) } // Handle commands that require an HTrace client. switch cmd { case version.FullCommand(): os.Exit(printVersion()) case serverInfo.FullCommand(): os.Exit(printServerInfo(hcl)) case serverStats.FullCommand(): if *serverStatsJson { os.Exit(printServerStatsJson(hcl)) } else { os.Exit(printServerStats(hcl)) } case findSpan.FullCommand(): var id *common.SpanId id.FromString(*findSpanId) os.Exit(doFindSpan(hcl, *id)) case findChildren.FullCommand(): var id *common.SpanId id.FromString(*parentSpanId) os.Exit(doFindChildren(hcl, *id, *childLim)) case loadJson.FullCommand(): os.Exit(doLoadSpanJson(hcl, *loadJsonArg)) case loadFile.FullCommand(): os.Exit(doLoadSpanJsonFile(hcl, *loadFilePath)) case dumpAll.FullCommand(): err := doDumpAll(hcl, *dumpAllOutPath, *dumpAllLim) if err != nil { fmt.Printf("dumpAll error: %s\n", err.Error()) os.Exit(EXIT_FAILURE) } os.Exit(EXIT_SUCCESS) case query.FullCommand(): err := doQueryFromString(hcl, *queryArg, *queryLim) if err != nil { fmt.Printf("query error: %s\n", err.Error()) os.Exit(EXIT_FAILURE) } os.Exit(EXIT_SUCCESS) case rawQuery.FullCommand(): err := doRawQuery(hcl, *rawQueryArg) if err != nil { fmt.Printf("raw query error: %s\n", err.Error()) os.Exit(EXIT_FAILURE) } os.Exit(EXIT_SUCCESS) } app.UsageErrorf(os.Stderr, "You must supply a command to run.") }