func startCollectdServer(w api.Writer) { if *collectdAddress == "" { return } srv := network.Server{ Addr: *collectdAddress, Writer: w, } if *collectdAuth != "" { srv.PasswordLookup = network.NewAuthFile(*collectdAuth) } switch strings.ToLower(*collectdSecurity) { case "", "none": srv.SecurityLevel = network.None case "sign": srv.SecurityLevel = network.Sign case "encrypt": srv.SecurityLevel = network.Encrypt default: log.Fatalf("Unknown security level %q. Must be one of \"None\", \"Sign\" and \"Encrypt\".", *collectdSecurity) } go func() { log.Fatal(srv.ListenAndWrite()) }() }
// Open starts the service. func (s *Service) Open() error { s.mu.Lock() defer s.mu.Unlock() if !s.closed() { return nil // Already open. } s.done = make(chan struct{}) s.Logger.Info("Starting collectd service") if s.Config.BindAddress == "" { return fmt.Errorf("bind address is blank") } else if s.Config.Database == "" { return fmt.Errorf("database name is blank") } else if s.PointsWriter == nil { return fmt.Errorf("PointsWriter is nil") } if s.popts.TypesDB == nil { // Open collectd types. if stat, err := os.Stat(s.Config.TypesDB); err != nil { return fmt.Errorf("Stat(): %s", err) } else if stat.IsDir() { alltypesdb := new(api.TypesDB) var readdir func(path string) readdir = func(path string) { files, err := ioutil.ReadDir(path) if err != nil { s.Logger.Info(fmt.Sprintf("Unable to read directory %s: %s\n", path, err)) return } for _, f := range files { fullpath := filepath.Join(path, f.Name()) if f.IsDir() { readdir(fullpath) continue } s.Logger.Info(fmt.Sprintf("Loading %s\n", fullpath)) types, err := TypesDBFile(fullpath) if err != nil { s.Logger.Info(fmt.Sprintf("Unable to parse collectd types file: %s\n", f.Name())) continue } alltypesdb.Merge(types) } } readdir(s.Config.TypesDB) s.popts.TypesDB = alltypesdb } else { s.Logger.Info(fmt.Sprintf("Loading %s\n", s.Config.TypesDB)) types, err := TypesDBFile(s.Config.TypesDB) if err != nil { return fmt.Errorf("Open(): %s", err) } s.popts.TypesDB = types } } // Sets the security level according to the config. // Default not necessary because we validate the config. switch s.Config.SecurityLevel { case "none": s.popts.SecurityLevel = network.None case "sign": s.popts.SecurityLevel = network.Sign case "encrypt": s.popts.SecurityLevel = network.Encrypt } // Sets the auth file according to the config. if s.popts.PasswordLookup == nil { s.popts.PasswordLookup = network.NewAuthFile(s.Config.AuthFile) } // Resolve our address. addr, err := net.ResolveUDPAddr("udp", s.Config.BindAddress) if err != nil { return fmt.Errorf("unable to resolve UDP address: %s", err) } s.addr = addr // Start listening conn, err := net.ListenUDP("udp", addr) if err != nil { return fmt.Errorf("unable to listen on UDP: %s", err) } if s.Config.ReadBuffer != 0 { err = conn.SetReadBuffer(s.Config.ReadBuffer) if err != nil { return fmt.Errorf("unable to set UDP read buffer to %d: %s", s.Config.ReadBuffer, err) } } s.conn = conn s.Logger.Info(fmt.Sprint("Listening on UDP: ", conn.LocalAddr().String())) // Start the points batcher. s.batcher = tsdb.NewPointBatcher(s.Config.BatchSize, s.Config.BatchPending, time.Duration(s.Config.BatchDuration)) s.batcher.Start() // Create waitgroup for signalling goroutines to stop and start goroutines // that process collectd packets. s.wg.Add(2) go func() { defer s.wg.Done(); s.serve() }() go func() { defer s.wg.Done(); s.writePoints() }() return nil }
func startCollectdServer(ctx context.Context, w api.Writer) { if *collectdAddress == "" { return } srv := network.Server{ Addr: *collectdAddress, Writer: w, } if *collectdAuth != "" { srv.PasswordLookup = network.NewAuthFile(*collectdAuth) } if *collectdTypesDB != "" { file, err := os.Open(*collectdTypesDB) if err != nil { log.Fatalf("Can't open types.db file %s", *collectdTypesDB) } defer file.Close() typesDB, err := api.NewTypesDB(file) if err != nil { log.Fatalf("Error in parsing types.db file %s", *collectdTypesDB) } srv.TypesDB = typesDB } switch strings.ToLower(*collectdSecurity) { case "", "none": srv.SecurityLevel = network.None case "sign": srv.SecurityLevel = network.Sign case "encrypt": srv.SecurityLevel = network.Encrypt default: log.Fatalf("Unknown security level %q. Must be one of \"None\", \"Sign\" and \"Encrypt\".", *collectdSecurity) } laddr, err := net.ResolveUDPAddr("udp", *collectdAddress) if err != nil { log.Fatalf("Failed to resolve binary protocol listening UDP address %q: %v", *collectdAddress, err) } if laddr.IP != nil && laddr.IP.IsMulticast() { srv.Conn, err = net.ListenMulticastUDP("udp", nil, laddr) } else { srv.Conn, err = net.ListenUDP("udp", laddr) } if err != nil { log.Fatalf("Failed to create a socket for a binary protocol server: %v", err) } if *collectdBuffer >= 0 { if err = srv.Conn.SetReadBuffer(*collectdBuffer); err != nil { log.Fatalf("Failed to adjust a read buffer of the socket: %v", err) } } go func() { log.Fatal(srv.ListenAndWrite(ctx)) }() }