Esempio n. 1
0
// NewServer returns a new instance of Server built from a config.
func NewServer(c *Config, buildInfo *BuildInfo, logService logging.Interface) (*Server, error) {
	err := c.Validate()
	if err != nil {
		return nil, fmt.Errorf("%s. To generate a valid configuration file run `kapacitord config > kapacitor.generated.conf`.", err)
	}
	l := logService.NewLogger("[srv] ", log.LstdFlags)
	s := &Server{
		buildInfo:     *buildInfo,
		dataDir:       c.DataDir,
		hostname:      c.Hostname,
		err:           make(chan error),
		LogService:    logService,
		MetaStore:     &metastore{},
		QueryExecutor: &queryexecutor{},
		Logger:        l,
	}
	s.Logger.Println("I! Kapacitor hostname:", s.hostname)

	// Start Task Master
	s.TaskMaster = kapacitor.NewTaskMaster(logService)
	if err := s.TaskMaster.Open(); err != nil {
		return nil, err
	}

	// Append Kapacitor services.
	s.appendUDFService(c.UDF)
	s.appendDeadmanService(c.Deadman)
	s.appendSMTPService(c.SMTP)
	s.appendHTTPDService(c.HTTP)
	s.appendInfluxDBService(c.InfluxDB, c.Hostname)
	s.appendTaskStoreService(c.Task)
	s.appendReplayStoreService(c.Replay)
	s.appendOpsGenieService(c.OpsGenie)
	s.appendVictorOpsService(c.VictorOps)
	s.appendPagerDutyService(c.PagerDuty)
	s.appendHipChatService(c.HipChat)
	s.appendAlertaService(c.Alerta)
	s.appendSlackService(c.Slack)

	// Append InfluxDB services
	s.appendCollectdService(c.Collectd)
	if err := s.appendOpenTSDBService(c.OpenTSDB); err != nil {
		return nil, err
	}
	for _, g := range c.UDPs {
		s.appendUDPService(g)
	}
	for _, g := range c.Graphites {
		if err := s.appendGraphiteService(g); err != nil {
			return nil, err
		}
	}

	// append StatsService and ReportingService last so all stats are ready
	// to be reported
	s.appendStatsService(c.Stats)
	s.appendReportingService(c.Reporting)

	return s, nil
}
Esempio n. 2
0
// New returns a new instance of Server built from a config.
func New(c *Config, buildInfo BuildInfo, logService logging.Interface) (*Server, error) {
	err := c.Validate()
	if err != nil {
		return nil, fmt.Errorf("%s. To generate a valid configuration file run `kapacitord config > kapacitor.generated.conf`.", err)
	}
	l := logService.NewLogger("[srv] ", log.LstdFlags)
	s := &Server{
		config:          c,
		BuildInfo:       buildInfo,
		dataDir:         c.DataDir,
		hostname:        c.Hostname,
		err:             make(chan error),
		configUpdates:   make(chan config.ConfigUpdate, 100),
		LogService:      logService,
		MetaClient:      &kapacitor.NoopMetaClient{},
		QueryExecutor:   &Queryexecutor{},
		Logger:          l,
		ServicesByName:  make(map[string]int),
		DynamicServices: make(map[string]Updater),
	}
	s.Logger.Println("I! Kapacitor hostname:", s.hostname)

	// Setup IDs
	err = s.setupIDs()
	if err != nil {
		return nil, err
	}

	// Set published vars
	kapacitor.ClusterIDVar.Set(s.ClusterID)
	kapacitor.ServerIDVar.Set(s.ServerID)
	kapacitor.HostVar.Set(s.hostname)
	kapacitor.ProductVar.Set(kapacitor.Product)
	kapacitor.VersionVar.Set(s.BuildInfo.Version)
	s.Logger.Printf("I! ClusterID: %s ServerID: %s", s.ClusterID, s.ServerID)

	// Start Task Master
	s.TaskMasterLookup = kapacitor.NewTaskMasterLookup()
	s.TaskMaster = kapacitor.NewTaskMaster(kapacitor.MainTaskMaster, logService)
	s.TaskMaster.DefaultRetentionPolicy = c.DefaultRetentionPolicy
	s.TaskMasterLookup.Set(s.TaskMaster)
	if err := s.TaskMaster.Open(); err != nil {
		return nil, err
	}

	// Append Kapacitor services.
	s.initHTTPDService()
	s.appendStorageService()
	s.appendAuthService()
	s.appendConfigOverrideService()
	s.appendTesterService()

	// Append all dynamic services after the config override and tester services.
	s.appendUDFService()
	s.appendDeadmanService()

	if err := s.appendInfluxDBService(); err != nil {
		return nil, errors.Wrap(err, "influxdb service")
	}
	// Append these after InfluxDB because they depend on it
	s.appendTaskStoreService()
	s.appendReplayService()

	// Append Alert integration services
	s.appendAlertaService()
	s.appendHipChatService()
	s.appendOpsGenieService()
	s.appendPagerDutyService()
	s.appendSMTPService()
	s.appendSensuService()
	s.appendSlackService()
	s.appendTalkService()
	s.appendTelegramService()
	s.appendVictorOpsService()

	// Append third-party integrations
	if err := s.appendK8sService(); err != nil {
		return nil, errors.Wrap(err, "kubernetes service")
	}

	// Append extra input services
	s.appendCollectdService()
	s.appendUDPServices()
	if err := s.appendOpenTSDBService(); err != nil {
		return nil, errors.Wrap(err, "opentsdb service")
	}
	if err := s.appendGraphiteServices(); err != nil {
		return nil, errors.Wrap(err, "graphite service")
	}

	// Append StatsService and ReportingService after other services so all stats are ready
	// to be reported
	s.appendStatsService()
	s.appendReportingService()

	// Append HTTPD Service last so that the API is not listening till everything else succeeded.
	s.appendHTTPDService()

	return s, nil
}
Esempio n. 3
0
// NewHandler returns a new instance of handler with routes.
func NewHandler(
	requireAuthentication,
	loggingEnabled,
	writeTrace,
	allowGzip bool,
	statMap *expvar.Map,
	l *log.Logger,
	li logging.Interface,
	sharedSecret string,
) *Handler {
	h := &Handler{
		methodMux:             make(map[string]*ServeMux),
		requireAuthentication: requireAuthentication,
		sharedSecret:          sharedSecret,
		allowGzip:             allowGzip,
		logger:                l,
		writeTrace:            writeTrace,
		clfLogger:             li.NewRawLogger("[httpd] ", 0),
		loggingEnabled:        loggingEnabled,
		statMap:               statMap,
	}

	allowedMethods := []string{
		"GET",
		"POST",
		"PATCH",
		"DELETE",
		"HEAD",
		"OPTIONS",
	}

	for _, method := range allowedMethods {
		h.methodMux[method] = NewServeMux()
		route := Route{
			// Catch all 404
			Name:        "404",
			Method:      method,
			Pattern:     "/",
			HandlerFunc: h.serve404,
		}
		h.addRawRoute(route)
	}

	h.addRawRoutes([]Route{
		{
			// Ping
			Name:        "ping",
			Method:      "GET",
			Pattern:     BasePath + "/ping",
			HandlerFunc: h.servePing,
		},
		{
			// Ping
			Name:        "ping-head",
			Method:      "HEAD",
			Pattern:     BasePath + "/ping",
			HandlerFunc: h.servePing,
		},
		{
			// Data-ingest route.
			Name:        "write",
			Method:      "POST",
			Pattern:     BasePath + "/write",
			HandlerFunc: h.serveWrite,
		},
		{
			// Satisfy CORS checks.
			Name:        "write",
			Method:      "OPTIONS",
			Pattern:     BasePath + "/write",
			HandlerFunc: ServeOptions,
		},
		{
			// Data-ingest route for /write endpoint without base path
			Name:        "write-raw",
			Method:      "POST",
			Pattern:     "/write",
			HandlerFunc: h.serveWrite,
		},
		{
			// Satisfy CORS checks.
			Name:        "write-raw",
			Method:      "OPTIONS",
			Pattern:     "/write",
			HandlerFunc: ServeOptions,
		},
		{
			// Display current API routes
			Name:        "routes",
			Method:      "GET",
			Pattern:     BasePath + "/:routes",
			HandlerFunc: h.serveRoutes,
		},
		{
			// Change current log level
			Name:        "log-level",
			Method:      "POST",
			Pattern:     BasePath + "/loglevel",
			HandlerFunc: h.serveLogLevel,
		},
		{
			Name:        "pprof",
			Method:      "GET",
			Pattern:     BasePath + "/debug/pprof/",
			HandlerFunc: pprof.Index,
			noJSON:      true,
		},
		{
			Name:        "pprof/cmdline",
			Method:      "GET",
			Pattern:     BasePath + "/debug/pprof/cmdline",
			HandlerFunc: pprof.Cmdline,
			noJSON:      true,
		},
		{
			Name:        "pprof/profile",
			Method:      "GET",
			Pattern:     BasePath + "/debug/pprof/profile",
			HandlerFunc: pprof.Profile,
			noJSON:      true,
		},
		{
			Name:        "pprof/symbol",
			Method:      "GET",
			Pattern:     BasePath + "/debug/pprof/symbol",
			HandlerFunc: pprof.Symbol,
			noJSON:      true,
		},
		{
			Name:        "pprof/trace",
			Method:      "GET",
			Pattern:     BasePath + "/debug/pprof/trace",
			HandlerFunc: pprof.Trace,
			noJSON:      true,
		},
		{
			Name:        "debug/vars",
			Method:      "GET",
			Pattern:     BasePath + "/debug/vars",
			HandlerFunc: serveExpvar,
		},
	})

	return h
}