func LoadApplicationConfig() *conf.Config { cnf, dlog := conf.LoadApplicationConfig() lg := NewLogger("conf", cnf) defer lg.Close() if lg.Level <= DEBUG { // Print out the debug information from loading the configuration. scanner := bufio.NewScanner(dlog) for scanner.Scan() { lg.Debugf(scanner.Text() + "\n") } } return cnf }
func main() { for idx := range os.Args { arg := os.Args[idx] if strings.HasPrefix(arg, "--h") || strings.HasPrefix(arg, "-h") { fmt.Fprintf(os.Stderr, USAGE) os.Exit(0) } } // Load the htraced configuration. cnf, cnfLog := conf.LoadApplicationConfig("htraced.") // Open the HTTP port. // We want to do this first, before initializing the datastore or setting up // logging. That way, if someone accidentally starts two daemons with the // same config file, the second invocation will exit with a "port in use" // error rather than potentially disrupting the first invocation. rstListener, listenErr := net.Listen("tcp", cnf.Get(conf.HTRACE_WEB_ADDRESS)) if listenErr != nil { fmt.Fprintf(os.Stderr, "Error opening HTTP port: %s\n", listenErr.Error()) os.Exit(1) } // Print out the startup banner and information about the daemon // configuration. lg := common.NewLogger("main", cnf) defer lg.Close() lg.Infof("*** Starting htraced %s [%s]***\n", RELEASE_VERSION, GIT_VERSION) scanner := bufio.NewScanner(cnfLog) for scanner.Scan() { lg.Infof(scanner.Text() + "\n") } common.InstallSignalHandlers(cnf) if runtime.GOMAXPROCS(0) == 1 { ncpu := runtime.NumCPU() runtime.GOMAXPROCS(ncpu) lg.Infof("setting GOMAXPROCS=%d\n", ncpu) } else { lg.Infof("GOMAXPROCS=%d\n", runtime.GOMAXPROCS(0)) } lg.Infof("leveldb version=%d.%d\n", levigo.GetLevelDBMajorVersion(), levigo.GetLevelDBMinorVersion()) // Initialize the datastore. store, err := CreateDataStore(cnf, nil) if err != nil { lg.Errorf("Error creating datastore: %s\n", err.Error()) os.Exit(1) } var rsv *RestServer rsv, err = CreateRestServer(cnf, store, rstListener) if err != nil { lg.Errorf("Error creating REST server: %s\n", err.Error()) os.Exit(1) } var hsv *HrpcServer if cnf.Get(conf.HTRACE_HRPC_ADDRESS) != "" { hsv, err = CreateHrpcServer(cnf, store, nil) if err != nil { lg.Errorf("Error creating HRPC server: %s\n", err.Error()) os.Exit(1) } } else { lg.Infof("Not starting HRPC server because no value was given for %s.\n", conf.HTRACE_HRPC_ADDRESS) } naddr := cnf.Get(conf.HTRACE_STARTUP_NOTIFICATION_ADDRESS) if naddr != "" { notif := StartupNotification{ HttpAddr: rsv.Addr().String(), ProcessId: os.Getpid(), } if hsv != nil { notif.HrpcAddr = hsv.Addr().String() } err = sendStartupNotification(naddr, ¬if) if err != nil { fmt.Fprintf(os.Stderr, "Failed to send startup notification: "+ "%s\n", err.Error()) os.Exit(1) } } for { time.Sleep(time.Duration(10) * time.Hour) } }
func main() { // Load htraced configuration cnf, cnfLog := conf.LoadApplicationConfig("htrace.tool.") lg := common.NewLogger("conf", cnf) defer lg.Close() scanner := bufio.NewScanner(cnfLog) for scanner.Scan() { lg.Debugf(scanner.Text() + "\n") } // 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.") serverVersion := app.Command("serverVersion", "Print the version of the 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() serverDebugInfo := app.Command("serverDebugInfo", "Print the debug info of the htraced server.") 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.") 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 := rawQuery.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, nil) 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 serverVersion.FullCommand(): os.Exit(printServerVersion(hcl)) case serverStats.FullCommand(): if *serverStatsJson { os.Exit(printServerStatsJson(hcl)) } else { os.Exit(printServerStats(hcl)) } case serverDebugInfo.FullCommand(): os.Exit(printServerDebugInfo(hcl)) case serverConf.FullCommand(): os.Exit(printServerConfJson(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.") }