func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
	desc := NewDesc(
		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
		opts.Help,
		labelNames,
		opts.ConstLabels,
	)
	return &CounterVec{
		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
			result := &counter{value: value{
				desc:       desc,
				valType:    CounterValue,
				labelPairs: makeLabelPairs(desc, lvs),
			}}
			result.init(result)  
			return result
		}),
	}
}
NewCounterVec creates a new CounterVec based on the provided CounterOpts and
partitioned by the given label names.
package prometheus
import (
	"errors"
)
type Counter interface {
	Metric
	Collector
	Inc()
	Add(float64)
}
type CounterOpts Opts
func NewCounter(opts CounterOpts) Counter {
	desc := NewDesc(
		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
		opts.Help,
		nil,
		opts.ConstLabels,
	)
	result := &counter{value: value{desc: desc, valType: CounterValue, labelPairs: desc.constLabelPairs}}
	result.init(result)  
	return result
}
type counter struct {
	value
}
func (c *counter) Add(v float64) {
	if v < 0 {
		panic(errors.New("counter cannot decrease in value"))
	}
	c.value.Add(v)
}
type CounterVec struct {
	*metricVec
}