registry.go
func (r *Registry) Flush() error {
	r.mutex.RLock()
	reporters := r.reporters
	rtags := r.tags
	r.mutex.RUnlock()

	for _, rep := range reporters {
		if err := rep.Prep(); err != nil {
			return err
		}
	}

	for metricID, val := range r.reset() {
		name, tags := SplitMetricID(metricID)
		if len(name) > 0 && name[0] == '|' {
			name = name[1:]
		} else {
			name = r.prefix + name
		}
		tags = append(tags, rtags...)

		switch inst := val.(type) {
		case Discrete:
			val := inst.Snapshot()
			for _, rep := range reporters {
				if err := rep.Discrete(name, tags, val); err != nil {
					return err
				}
			}
		case Sample:
			val := inst.Snapshot()
			for _, rep := range reporters {
				if err := rep.Sample(name, tags, val); err != nil {
					return err
				}
			}
			releaseDistribution(val)
		}
	}

	for _, rep := range reporters {
		if err := rep.Flush(); err != nil {
			return err
		}
	}
	return nil
}
func (r *Registry) Flush() error {
	r.mutex.RLock()
	reporters := r.reporters
	rtags := r.tags
	r.mutex.RUnlock()

	for _, rep := range reporters {
		if err := rep.Prep(); err != nil {
			return err
		}
	}

	for metricID, val := range r.reset() {
		name, tags := SplitMetricID(metricID)
		if len(name) > 0 && name[0] == '|' {
			name = name[1:]
		} else {
			name = r.prefix + name
		}
		tags = append(tags, rtags...)

		switch inst := val.(type) {
		case Discrete:
			val := inst.Snapshot()
			for _, rep := range reporters {
				if err := rep.Discrete(name, tags, val); err != nil {
					return err
				}
			}
		case Sample:
			val := inst.Snapshot()
			for _, rep := range reporters {
				if err := rep.Sample(name, tags, val); err != nil {
					return err
				}
			}
			releaseDistribution(val)
		}
	}

	for _, rep := range reporters {
		if err := rep.Flush(); err != nil {
			return err
		}
	}
	return nil
}
// Flush performs a manual flush to all subscribed reporters.
// This method is usually called by a background thread
// every flushInterval, specified in New()