Beispiel #1
0
func main() {
	// Create a recent in-memory store, evicting data after 20s.
	//
	// The store defines where information about traces (i.e. spans and
	// annotations) will be stored during the lifetime of the application. This
	// application uses a MemoryStore store wrapped by a RecentStore with an
	// eviction time of 20s (i.e. all data after 20s is deleted from memory).
	memStore := appdash.NewMemoryStore()
	store := &appdash.RecentStore{
		MinEvictAge: 20 * time.Second,
		DeleteStore: memStore,
	}

	// Start the Appdash web UI on port 8700.
	//
	// This is the actual Appdash web UI -- usable as a Go package itself, We
	// embed it directly into our application such that visiting the web server
	// on HTTP port 8700 will bring us to the web UI, displaying information
	// about this specific web-server (another alternative would be to connect
	// to a centralized Appdash collection server).
	url, err := url.Parse("http://localhost:8700")
	if err != nil {
		log.Fatal(err)
	}
	tapp, err := traceapp.New(nil, url)
	if err != nil {
		log.Fatal(err)
	}
	tapp.Store = store
	tapp.Queryer = memStore
	log.Println("Appdash web UI running on HTTP :8700")
	go func() {
		log.Fatal(http.ListenAndServe(":8700", tapp))
	}()

	// We will use a local collector (as we are running the Appdash web UI
	// embedded within our app).
	//
	// A collector is responsible for collecting the information about traces
	// (i.e. spans and annotations) and placing them into a store. In this app
	// we use a local collector (we could also use a remote collector, sending
	// the information to a remote Appdash collection server).
	collector := appdash.NewLocalCollector(store)

	// Here we use the local collector to create a new opentracing.Tracer
	tracer := appdashtracer.NewTracer(collector)
	opentracing.InitGlobalTracer(tracer)

	// Setup our router (for information, see the gorilla/mux docs):
	router := mux.NewRouter()
	router.HandleFunc("/", Home)
	router.HandleFunc("/endpoint", Endpoint)

	// Setup Negroni for our app (for information, see the negroni docs):
	n := negroni.Classic()
	n.UseHandler(router)
	n.Run(":8699")
}
Beispiel #2
0
func main() {
	var (
		debugAddr   = flag.String("debug.addr", ":8080", "Debug and metrics listen address")
		grpcAddr    = flag.String("grpc.addr", ":8082", "gRPC (HTTP) listen address")
		appdashAddr = flag.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port")
		ircNick     = flag.String("irc.nick", "gogrpctest", "IRC nickname")
		ircSecret   = flag.String("irc.secret", "", "IRC password")
		ircHost     = flag.String("irc.addr", "irc.freenode.net:6667", "IRC host system")
	)
	flag.Parse()

	// Logging domain.
	var logger log.Logger
	{
		logger = log.NewLogfmtLogger(os.Stdout)
		logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
		logger = log.NewContext(logger).With("caller", log.DefaultCaller)
	}
	logger.Log("msg", "hello")
	defer logger.Log("msg", "goodbye")

	// Metrics domain.
	var cx, cxerr, joins metrics.Counter
	{
		// Business level metrics.
		cx = prometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "relay",
			Name:      "connect_succeeded",
			Help:      "Total count of connects via the Connect method.",
		}, []string{})
		cxerr = prometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "relay",
			Name:      "connect_failed",
			Help:      "Total count of connect errors via the Connect method.",
		}, []string{})
		joins = prometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "relay",
			Name:      "channels_joined",
			Help:      "Total count of channels joined via the Join method.",
		}, []string{})
	}
	var duration metrics.Histogram
	{
		// Transport level metrics.
		duration = prometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "relay",
			Name:      "request_duration_ns",
			Help:      "Request duration in nanoseconds.",
		}, []string{"method", "success"})
	}

	// Tracing domain.
	var tracer stdopentracing.Tracer
	{
		if *appdashAddr != "" {
			logger := log.NewContext(logger).With("tracer", "Appdash")
			logger.Log("addr", *appdashAddr)
			tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr))
		} else {
			logger := log.NewContext(logger).With("tracer", "none")
			logger.Log()
			tracer = stdopentracing.GlobalTracer() // no-op
		}
	}

	// Business domain.
	var service relay.Service
	{
		service = relay.NewBasicService(*ircNick, *ircHost, *ircSecret)
		service = relay.ServiceLoggingMiddleware(logger)(service)
		service = relay.ServiceInstrumentingMiddleware(cx, cxerr, joins)(service)
	}

	// Endpoint domain.
	var connectEndpoint endpoint.Endpoint
	{
		connectDuration := duration.With("method", "Connect")
		connectLogger := log.NewContext(logger).With("method", "Connect")

		connectEndpoint = relay.MakeConnectEndpoint(service)
		connectEndpoint = opentracing.TraceServer(tracer, "Connect")(connectEndpoint)
		connectEndpoint = relay.EndpointInstrumentingMiddleware(connectDuration)(connectEndpoint)
		connectEndpoint = relay.EndpointLoggingMiddleware(connectLogger)(connectEndpoint)
	}
	var joinEndpoint endpoint.Endpoint
	{
		joinDuration := duration.With("method", "Join")
		joinLogger := log.NewContext(logger).With("method", "Join")

		joinEndpoint = relay.MakeJoinEndpoint(service)
		joinEndpoint = opentracing.TraceServer(tracer, "Join")(joinEndpoint)
		joinEndpoint = relay.EndpointInstrumentingMiddleware(joinDuration)(joinEndpoint)
		joinEndpoint = relay.EndpointLoggingMiddleware(joinLogger)(joinEndpoint)
	}
	endpoints := relay.Endpoints{
		ConnectEndpoint: connectEndpoint,
		JoinEndpoint:    joinEndpoint,
	}

	// Mechanical domain.
	errc := make(chan error)
	ctx := context.Background()

	// Interrupt handler.
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errc <- fmt.Errorf("%s", <-c)
	}()

	// Debug listener.
	go func() {
		logger := log.NewContext(logger).With("transport", "debug")

		m := http.NewServeMux()
		m.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
		m.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
		m.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
		m.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
		m.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
		m.Handle("/metrics", stdprometheus.Handler())

		logger.Log("addr", *debugAddr)
		errc <- http.ListenAndServe(*debugAddr, m)
	}()

	// gRPC transport.
	go func() {
		logger := log.NewContext(logger).With("transport", "gRPC")

		ln, err := net.Listen("tcp", *grpcAddr)
		if err != nil {
			errc <- err
			return
		}

		srv := relay.MakeGRPCServer(ctx, endpoints, tracer, logger)
		s := grpc.NewServer()
		pb.RegisterRelayServer(s, srv)

		logger.Log("addr", *grpcAddr)
		errc <- s.Serve(ln)
	}()

	// Run!
	logger.Log("exit", <-errc)
}
Beispiel #3
0
func main() {
	// The relaycli presumes no service discovery system, and expects users to
	// provide the direct address of a relaysvc. This presumption is reflected in
	// the relaycli binary and the the client packages: the -transport.addr flags
	// and various client constructors both expect host:port strings.

	var (
		grpcAddr    = flag.String("grpc.addr", "", "gRPC (HTTP) address of relaysvc")
		appdashAddr = flag.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port")
		method      = flag.String("method", "connect", "connect, join")
	)
	flag.Parse()

	if len(flag.Args()) != 1 {
		fmt.Fprintf(os.Stderr, "usage: relaycli [flags] <s>\n")
		os.Exit(1)
	}

	var tracer stdopentracing.Tracer
	{
		if *appdashAddr != "" {
			tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr))
		} else {
			tracer = stdopentracing.GlobalTracer() // no-op
		}
	}

	var (
		service relay.Service
		err     error
	)
	if *grpcAddr != "" {
		conn, err := grpc.Dial(*grpcAddr, grpc.WithInsecure(), grpc.WithTimeout(time.Second))
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %v", err)
			os.Exit(1)
		}
		defer conn.Close()
		service = grpcclient.New(conn, tracer, log.NewNopLogger())
	} else {
		fmt.Fprintf(os.Stderr, "error: no remote address specified\n")
		os.Exit(1)
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	switch *method {
	case "connect":
		s := flag.Args()[0]
		v, err := service.Connect(context.Background(), s)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %v\n", err)
			os.Exit(1)
		}
		fmt.Fprintf(os.Stdout, "Connect to %s: %s\n", s, v)

	case "join":
		c := flag.Args()[0]
		v, err := service.Join(context.Background(), c)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error: %v\n", err)
			os.Exit(1)
		}
		fmt.Fprintf(os.Stdout, "Join channel %s: %s\n", c, v)

	default:
		fmt.Fprintf(os.Stderr, "error: invalid method %q\n", method)
		os.Exit(1)
	}
}