Beispiel #1
0
func (manager *DrainManager) StartDrain(name, uri string, retry retry.Retryer) {
	manager.mux.Lock()
	defer manager.mux.Unlock()

	var stateChangeFn state.StateChangedFn

	_, exists := manager.stmMap[name]
	if exists {
		// Stop the running drain first.
		manager.stopDrain(name, false)
	} else {
		stateChangeFn = func(state state.State, rev int64) {
			manager.stateCache.SetState(name, state, rev)
		}
	}

	process, err := NewDrainProcess(name, uri)
	if err != nil {
		log.Error(process.Logf("Couldn't create drain: %v", err))
		return
	}
	drainStm := state.NewStateMachine("Drain", process, retry, stateChangeFn)
	manager.stmMap[name] = drainStm

	if err = drainStm.SendAction(state.START); err != nil {
		log.Fatalf("Failed to start drain %s; %v", name, err)
	}
}
Beispiel #2
0
func createLogyardConfig() {
	g, err := server.NewConfig("logyard", logyardConfig{})
	if err != nil {
		log.Fatalf("Unable to load logyard config; %v", err)
	}
	config = g
	if config.GetConfig().(*logyardConfig).Drains == nil {
		log.Fatal("Logyard configuration is missing")
	}
}
Beispiel #3
0
// stopDrain should only be called inside a mutex.
func (manager *DrainManager) stopDrain(drainName string, clearStateCache bool) {
	if drainStm, ok := manager.stmMap[drainName]; ok {
		if err := drainStm.SendAction(state.STOP); err != nil {
			log.Fatalf("Failed to stop drain %s; %v", drainName, err)
		}
		drainStm.Stop()
		delete(manager.stmMap, drainName)
		if clearStateCache {
			manager.stateCache.Clear(drainName)
		}
	}
	// Sending on stopCh could block if DrainManager.Run().select
	// {...} is blocking on a mutex (via Start/Stop). Ideally, get rid
	// of mutexes and use channels.
	go func() {
		manager.stopCh <- true
	}()
}
Beispiel #4
0
func NewDrainManager() *DrainManager {
	manager := new(DrainManager)
	manager.stopCh = make(chan bool)
	manager.stmMap = make(map[string]*state.StateMachine)
	client, err := server.NewRedisClientRetry(
		server.GetClusterConfig().MbusIp+":6464",
		"",
		0,
		-1)
	if err != nil {
		log.Fatalf("Unable to connect to applog_redis; %v", err)
	}
	manager.stateCache = &statecache.StateCache{
		"logyard:drainstatus:",
		server.LocalIPMust(),
		client}
	return manager
}
Beispiel #5
0
func (manager *DrainManager) Run() {
	iteration := 0
	drains := logyard.GetConfig().Drains
	log.Infof("Found %d drains to start\n", len(drains))
	for name, uri := range drains {
		manager.StartDrain(name, uri, NewRetryerForDrain(name))
	}

	// Watch for config changes in redis.
	for {
		iteration += 1
		prefix := fmt.Sprintf("CONFIG.%d", iteration)

		select {
		case err := <-logyard.GetConfigChanges():
			if err != nil {
				log.Fatalf("Error re-loading config: %v", err)
			}
			log.Infof(
				"[%s] checking drains after a config change...",
				prefix)
			newDrains := logyard.GetConfig().Drains
			for _, c := range mapdiff.MapDiff(drains, newDrains) {
				if c.Deleted {
					log.Infof("[%s] Drain %s was deleted.", prefix, c.Key)
					manager.StopDrain(c.Key, true)
					delete(drains, c.Key)
				} else {
					log.Infof("[%s] Drain %s was added.", prefix, c.Key)
					manager.StopDrain(c.Key, false)
					manager.StartDrain(
						c.Key,
						c.NewValue,
						NewRetryerForDrain(c.Key))
					drains[c.Key] = c.NewValue
				}
			}
			log.Infof("[%s] Done checking drains.", prefix)
		case <-manager.stopCh:
			break
		}
	}
}
Beispiel #6
0
func Stream(ch chan string, options MessagePrinterOptions) {
	// XXX: do we need MessagePrinter at all? all it does is
	// provide abstraction over color formatting; most other things
	// (formatting, skipping) happen in handler.go.
	printer := NewMessagePrinter(options)

	printer.AddFormat("systail",
		"{{.name}}@{{.node_id}}: {{.text}}")
	printer.AddFormat("event",
		"{{.type}}[{{.process}}]@{{.node_id}}: {{.desc}}")
	printer.AddFormat("apptail",
		"{{.app_name}}[{{.source}}]@{{.node_id}}: {{.text}}")

	printer.SetPrePrintHook(streamHandler)

	// Print incoming records
	for line := range ch {
		parts := strings.SplitN(string(line), " ", 2)
		if len(parts) != 2 {
			printer.PrintInternalError(fmt.Sprintf(
				"received invalid message: %v", string(line)))
			continue
		}
		msg := zmqpubsub.Message{parts[0], parts[1]}
		if !(strings.HasPrefix(msg.Key, "systail") ||
			strings.HasPrefix(msg.Key, "apptail") ||
			strings.HasPrefix(msg.Key, "event")) {
			printer.PrintInternalError(fmt.Sprintf(
				"unsupported stream key (%s) for message: %v",
				msg.Key, msg.Value))
			continue
		}
		if err := printer.Print(msg); err != nil {
			log.Fatalf("Error -- %s -- printing message %s:%s",
				err, msg.Key, msg.Value)
		}
	}
}