func()

in exporter/collector/metrics.go [666:711]


func (me *MetricsExporter) runWALReadAndExportLoop(ctx context.Context) {
	defer me.goroutines.Done()
	defer func() {
		if err := me.wal.Close(); err != nil {
			me.obs.log.Error(fmt.Sprintf("error closing WAL: %+v\n", err))
		}
	}()
	for {
		select {
		case <-ctx.Done():
			return
		case <-me.shutdownC:
			// do one last final read/export then return
			// otherwise the runner goroutine could leave some hanging metrics unexported
			for {
				err := me.readWALAndExport(ctx)
				if err != nil {
					if !errors.Is(err, wal.ErrOutOfRange) {
						me.obs.log.Error(fmt.Sprintf("error flushing remaining WAL entries: %+v", err))
					}
					break
				}
			}
			return
		default:
			err := me.readWALAndExport(ctx)
			if err == nil {
				continue
			}
			// ErrNotFound from wal.Read() means the index is either 0 or out of
			// bounds (indicating we're probably at the end of the WAL). That error
			// will trigger a file watch for new writes (below this). For other
			// errors, fail.
			// ErrNotFound can be expected occasionally if we've reached the end of
			// the WAL, so don't bother logging those.
			if !errors.Is(err, wal.ErrNotFound) {
				me.obs.log.Error(fmt.Sprintf("error reading WAL and exporting: %+v", err))
			}

			// Must have been ErrNotFound, start a file watch and block waiting for updates.
			if err = me.watchWALFile(ctx); err != nil {
				me.obs.log.Error(fmt.Sprintf("error watching WAL and exporting: %+v", err))
			}
		}
	}
}