func NewDecoder() Decoder { // Get supported metrics. return &defaultDecoder{ supportedStatMetrics: sinksV1Api.SupportedStatMetrics(), lastExported: make(map[timeseriesKey]time.Time), } }
func (a *Api) exportMetricsSchema(request *restful.Request, response *restful.Response) { result := TimeseriesSchema{} for _, label := range sinksApi.CommonLabels() { result.CommonLabels = append(result.CommonLabels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } for _, label := range sinksApi.PodLabels() { result.PodLabels = append(result.PodLabels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } for _, metric := range sinksApi.SupportedStatMetrics() { md := MetricDescriptor{ Name: metric.Name, Description: metric.Description, Type: metric.Type.String(), ValueType: metric.ValueType.String(), Units: metric.Units.String(), } for _, label := range metric.Labels { md.Labels = append(md.Labels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } result.Metrics = append(result.Metrics, md) } response.WriteEntity(result) }
// NewExternalSinkManager returns an external sink manager that will manage pushing data to all // the sinks in 'externalSinks', which is a map of sink name to ExternalSink object. func NewExternalSinkManager(externalSinks []sink_api.ExternalSink) (ExternalSinkManager, error) { // Get supported metrics. supportedMetrics := sink_api.SupportedStatMetrics() for i := range supportedMetrics { supportedMetrics[i].Labels = sink_api.SupportedLabels() } // Create the metrics. descriptors := make([]sink_api.MetricDescriptor, 0, len(supportedMetrics)) for _, supported := range supportedMetrics { descriptors = append(descriptors, supported.MetricDescriptor) } for _, externalSink := range externalSinks { err := externalSink.Register(descriptors) if err != nil { return nil, err } } decoder := sink_api_old.NewDecoder() return &externalSinkManager{ externalSinks: externalSinks, decoder: decoder, }, nil }
func supportedMetricsDescriptors() []sink_api.MetricDescriptor { // Get supported metrics. supportedMetrics := sink_api.SupportedStatMetrics() for i := range supportedMetrics { supportedMetrics[i].Labels = sink_api.SupportedLabels() } // Create the metrics. descriptors := make([]sink_api.MetricDescriptor, 0, len(supportedMetrics)) for _, supported := range supportedMetrics { descriptors = append(descriptors, supported.MetricDescriptor) } return descriptors }
func (self *externalSinkManager) DebugInfo() string { desc := "External Sinks\n" // Add metrics being exported. desc += "\tExported metrics:\n" for _, supported := range sink_api.SupportedStatMetrics() { desc += fmt.Sprintf("\t\t%s: %s", supported.Name, supported.Description) } // Add labels being used. desc += "\n\tExported labels:\n" for _, label := range sink_api.SupportedLabels() { desc += fmt.Sprintf("\t\t%s: %s", label.Key, label.Description) } desc += "\n\tExternal Sinks:\n" for _, externalSink := range self.externalSinks { desc += fmt.Sprintf("\n\t\t%s", externalSink.DebugInfo()) } return desc }
func (self *externalSinkManager) DebugInfo() string { b := &bytes.Buffer{} fmt.Fprintln(b, "External Sinks") // Add metrics being exported. fmt.Fprintln(b, "\tExported metrics:") for _, supported := range sink_api.SupportedStatMetrics() { fmt.Fprintf(b, "\t\t%s: %s\n", supported.Name, supported.Description) } // Add labels being used. fmt.Fprintln(b, "\tExported labels:") for _, label := range sink_api.SupportedLabels() { fmt.Fprintf(b, "\t\t%s: %s\n", label.Key, label.Description) } fmt.Fprintln(b, "\tExternal Sinks:") self.sinkMutex.RLock() defer self.sinkMutex.RUnlock() for _, externalSink := range self.externalSinks { fmt.Fprintf(b, "\t\t%s\n", externalSink.DebugInfo()) } return b.String() }
func TestRealInput(t *testing.T) { containers := []source_api.Container{ getContainer("container1"), } pods := []source_api.Pod{ { PodMetadata: source_api.PodMetadata{ Name: "pod1", ID: "123", Namespace: "test", Hostname: "1.2.3.4", Status: "Running", }, Containers: containers, }, { PodMetadata: source_api.PodMetadata{ Name: "pod2", ID: "123", Namespace: "test", Hostname: "1.2.3.5", Status: "Running", }, Containers: containers, }, } input := source_api.AggregateData{ Pods: pods, Containers: containers, Machine: containers, } timeseries, err := NewDecoder().Timeseries(input) assert.NoError(t, err) assert.NotEmpty(t, timeseries) expectedFsStats := getFsStats(input) metrics := make(map[string][]sink_api.Timeseries) for index := range timeseries { series, ok := metrics[timeseries[index].Point.Name] if !ok { series = make([]sink_api.Timeseries, 0) } series = append(series, timeseries[index]) metrics[timeseries[index].Point.Name] = series } statMetrics := sink_api.SupportedStatMetrics() for index := range statMetrics { series, ok := metrics[statMetrics[index].MetricDescriptor.Name] require.True(t, ok) for innerIndex, entry := range series { assert.Equal(t, statMetrics[index].MetricDescriptor, *series[innerIndex].MetricDescriptor) spec := containers[0].Spec stats := containers[0].Stats[0] switch entry.Point.Name { case "uptime": _, ok := entry.Point.Value.(int64) require.True(t, ok) case "cpu/usage": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Cpu.Usage.Total, value) case "memory/usage": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Memory.Usage, value) case "memory/working_set": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Memory.WorkingSet, value) case "memory/page_faults": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Memory.ContainerData.Pgfault, value) case "memory/major_page_faults": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Memory.ContainerData.Pgmajfault, value) case "network/rx": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Network.RxBytes, value) case "network/rx_errors": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Network.RxErrors, value) case "network/tx": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Network.TxBytes, value) case "network/tx_errors": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, stats.Network.TxErrors, value) case "filesystem/usage": value, ok := entry.Point.Value.(int64) require.True(t, ok) name, ok := entry.Point.Labels[sink_api.LabelResourceID.Key] require.True(t, ok) assert.Equal(t, expectedFsStats[name].usage, value) case "cpu/limit": value, ok := entry.Point.Value.(int64) require.True(t, ok) expected := (spec.Cpu.Limit * 1000) / 1024 assert.Equal(t, expected, value) case "memory/limit": value, ok := entry.Point.Value.(int64) require.True(t, ok) assert.Equal(t, spec.Memory.Limit, value) case "filesystem/limit": value, ok := entry.Point.Value.(int64) require.True(t, ok) name, ok := entry.Point.Labels[sink_api.LabelResourceID.Key] require.True(t, ok) assert.Equal(t, expectedFsStats[name].limit, value) default: t.Errorf("unexpected metric type") } } } }