Exemplo n.º 1
0
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
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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.")
}