func Logs()

in cmd/hub/api/logs.go [44:188]


func Logs(selectors []string, exitOnCompletedOperation bool) int {
	filters := parseFilters(selectors)
	if len(selectors) > 0 && len(filters) == 0 {
		msg := fmt.Sprintf("No entities found by %v", selectors)
		if config.Force {
			config.AggWarnings = false
			util.Warn("%s", msg)
		} else {
			log.Fatalf("%s", msg)
		}
	}

	updates := make(chan WsMessage, 2)
	exitCode := make(chan int)
	var names sync.Map
	key := func(m *WsMessage) string {
		return m.Entity + ":" + m.Id
	}

	reconnects := 0
	var connect func()
	connect = func() {
		onDisconnect := func() {
			time.Sleep(1000)
			reconnects++
			if config.Debug {
				log.Printf("Reconnecting (%d)...", reconnects)
			}
			go connect()
		}

		ws, err := hubWsSocketIo(
			func() {
				if config.Verbose && reconnects == 0 {
					log.Print("Reading updates from WebSocket...")
				}
			},
			onDisconnect, onDisconnect)
		if err != nil {
			if reconnects == 0 {
				log.Fatalf("Unable to connect Hub WebSocket: %v", err)
			} else {
				go onDisconnect()
				return
			}
		}

		ws.On("change", func(ch *gosocketio.Channel, args []WsMessage) {
			m := WsMessage{}
			for _, arg := range args {
				if arg.Id != "" {
					m.Id = arg.Id
				}
				if arg.Name != "" {
					m.Name = arg.Name
				}
				if arg.Entity != "" {
					m.Entity = arg.Entity
					m.Action = arg.Action
					m.Success = arg.Success
				}
				if arg.Logs != "" {
					m.Logs = arg.Logs
				}

				if config.Debug {
					if !config.Trace && arg.Logs != "" {
						arg.Logs = util.TrimColor(util.Wrap(arg.Logs))
					}
					fmt.Printf("%s\n", aurora.Cyan(fmt.Sprintf("%+v", arg)).Bold().String())
				}
			}
			if m.Id != "" && m.Entity != "" {
				k := key(&m)
				if m.Name != "" {
					names.LoadOrStore(k, m.Name)
				} else {
					if maybeStr, ok := names.Load(k); ok {
						if str, ok := maybeStr.(string); ok {
							m.Name = str
						}
					}
				}
			}
			updates <- m
		})
	}

	connect()

	for {
		select {
		case code := <-exitCode:
			return code

		case m := <-updates:
			if len(filters) > 0 && !filterMatch(filters, &m) {
				continue
			}
			if m.Logs != "" {
				os.Stdout.Write([]byte(m.Logs))
				if strings.HasSuffix(m.Action, "-update") {
					continue
				}
			}
			success := aurora.Green("success").String()
			if !m.Success {
				success = aurora.Red("fail").String()
			}
			fmt.Printf("%s %s %s [%s] %s %s %s\n",
				aurora.Magenta("===>").Bold().String(),
				time.Now().Format("15:04:05"),
				aurora.Green(m.Name).String(),
				m.Id,
				m.Entity,
				aurora.Cyan(m.Action).String(),
				success)

			if exitOnCompletedOperation && (util.Contains(opCompletedActions, m.Action) ||
				(m.Entity == "application" && m.Action == "update")) {

				exit := true
				success := m.Success
				if len(filters) > 0 {
					markCompletedFilters(filters, &m)
					exit, success = allFiltersCompleted(filters)
				}
				if exit {
					if config.Debug {
						log.Print("Logs completed, exiting")
					}
					code := 0
					if !success {
						code = 2
					}
					// wait for updates and logs to catch-up
					go func() {
						time.Sleep(1 * time.Second)
						exitCode <- code
					}()
				}
			}
		}
	}
}