// 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 }
// 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 }
// 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 }