Copyright 2019, OpenCensus Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package metricexport

import (
	
	
	
	

	
	
	
)

var (
	defaultSampler             = trace.ProbabilitySampler(0.0001)
	errReportingIntervalTooLow = fmt.Errorf("reporting interval less than %d", minimumReportingDuration)
	errAlreadyStarted          = fmt.Errorf("already started")
	errIntervalReaderNil       = fmt.Errorf("interval reader is nil")
	errExporterNil             = fmt.Errorf("exporter is nil")
	errReaderNil               = fmt.Errorf("reader is nil")
)

const (
	defaultReportingDuration = 60 * time.Second
	minimumReportingDuration = 1 * time.Second
	defaultSpanName          = "ExportMetrics"
)
ReaderOptions contains options pertaining to metrics reader.
SpanName is the name used for span created to export metrics.
Reader reads metrics from all producers registered with producer manager and exports those metrics using provided exporter.
IntervalReader periodically reads metrics from all producers registered with producer manager and exports those metrics using provided exporter. Call Reader.Stop() to stop the reader.
ReportingInterval it the time duration between two consecutive metrics reporting. defaultReportingDuration is used if it is not set. It cannot be set lower than minimumReportingDuration.
ReaderOption apply changes to ReaderOptions.
WithSpanName makes new reader to use given span name when exporting metrics.
func ( string) ReaderOption {
	return func( *ReaderOptions) {
		.SpanName = 
	}
}
NewReader returns a reader configured with specified options.
func ( ...ReaderOption) *Reader {
	var  ReaderOptions
	for ,  := range  {
		(&)
	}
	 := &Reader{defaultSampler, defaultSpanName}
	if .SpanName != "" {
		.spanName = .SpanName
	}
	return 
}
NewIntervalReader creates a reader. Once started it periodically reads metrics from all producers and exports them using provided exporter.
func ( *Reader,  Exporter) (*IntervalReader, error) {
	if  == nil {
		return nil, errExporterNil
	}
	if  == nil {
		return nil, errReaderNil
	}

	 := &IntervalReader{
		exporter: ,
		reader:   ,
	}
	return , nil
}
Start starts the IntervalReader which periodically reads metrics from all producers registered with global producer manager. If the reporting interval is not set prior to calling this function then default reporting interval is used.
func ( *IntervalReader) () error {
	if  == nil {
		return errIntervalReaderNil
	}
	.mu.Lock()
	defer .mu.Unlock()
	var  = defaultReportingDuration
	if .ReportingInterval != 0 {
		if .ReportingInterval < minimumReportingDuration {
			return errReportingIntervalTooLow
		}
		 = .ReportingInterval
	}

	if .done != nil {
		return errAlreadyStarted
	}
	.timer = time.NewTicker()
	.quit = make(chan bool)
	.done = make(chan bool)

	go .startInternal()
	return nil
}

func ( *IntervalReader) () {
	for {
		select {
		case <-.timer.C:
			.reader.ReadAndExport(.exporter)
		case <-.quit:
			.timer.Stop()
			.done <- true
			return
		}
	}
}
Stop stops the reader from reading and exporting metrics. Additional call to Stop are no-ops.
func ( *IntervalReader) () {
	if  == nil {
		return
	}
	.mu.Lock()
	defer .mu.Unlock()
	if .quit == nil {
		return
	}
	.quit <- true
	<-.done
	close(.quit)
	close(.done)
	.quit = nil
}
ReadAndExport reads metrics from all producer registered with producer manager and then exports them using provided exporter.
func ( *Reader) ( Exporter) {
	,  := trace.StartSpan(context.Background(), .spanName, trace.WithSampler(.sampler))
	defer .End()
	 := metricproducer.GlobalManager().GetAll()
	 := []*metricdata.Metric{}
	for ,  := range  {
		 = append(, .Read()...)
TODO: [rghetia] add metrics for errors.
	.ExportMetrics(, )