Skip to content

Commit

Permalink
Move derived stats to v2. Add v2 container spec.
Browse files Browse the repository at this point in the history
  • Loading branch information
rjnagal committed Mar 4, 2015
1 parent 7839dd8 commit d3db850
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 59 deletions.
24 changes: 23 additions & 1 deletion api/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/golang/glog"
"github.com/google/cadvisor/events"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v2"
"github.com/google/cadvisor/manager"
)

Expand Down Expand Up @@ -330,8 +331,29 @@ func (self *version2_0) HandleRequest(requestType string, request []string, m ma
if err != nil {
return err
}
return writeResult(spec, w)
specV2 := convertSpec(spec)
return writeResult(specV2, w)
default:
return self.baseVersion.HandleRequest(requestType, request, m, w, r)
}
}

// Convert container spec from v1 to v2.
func convertSpec(specV1 info.ContainerSpec) v2.ContainerSpec {
specV2 := v2.ContainerSpec{
CreationTime: specV1.CreationTime,
HasCpu: specV1.HasCpu,
HasMemory: specV1.HasMemory,
}
if specV1.HasCpu {
specV2.Cpu.Limit = specV1.Cpu.Limit
specV2.Cpu.MaxLimit = specV1.Cpu.MaxLimit
specV2.Cpu.Mask = specV1.Cpu.Mask
}
if specV1.HasMemory {
specV2.Memory.Limit = specV1.Memory.Limit
specV2.Memory.Reservation = specV1.Memory.Reservation
specV2.Memory.SwapLimit = specV1.Memory.SwapLimit
}
return specV2
}
44 changes: 0 additions & 44 deletions info/v1/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,47 +455,3 @@ func calculateCpuUsage(prev, cur uint64) uint64 {
}
return cur - prev
}

type Percentiles struct {
// Indicates whether the stats are present or not.
// If true, values below do not have any data.
Present bool `json:"present"`
// Average over the collected sample.
Mean uint64 `json:"mean"`
// Max seen over the collected sample.
Max uint64 `json:"max"`
// 90th percentile over the collected sample.
Ninety uint64 `json:"ninety"`
}

type Usage struct {
// Indicates amount of data available [0-100].
// If we have data for half a day, we'll still process DayUsage,
// but set PercentComplete to 50.
PercentComplete int32 `json:"percent_complete"`
// Mean, Max, and 90p cpu rate value in milliCpus/seconds. Converted to milliCpus to avoid floats.
Cpu Percentiles `json:"cpu"`
// Mean, Max, and 90p memory size in bytes.
Memory Percentiles `json:"memory"`
}

// latest sample collected for a container.
type InstantUsage struct {
// cpu rate in cpu milliseconds/second.
Cpu uint64 `json:"cpu"`
// Memory usage in bytes.
Memory uint64 `json:"memory"`
}

type DerivedStats struct {
// Time of generation of these stats.
Timestamp time.Time `json:"timestamp"`
// Latest instantaneous sample.
LatestUsage InstantUsage `json:"latest_usage"`
// Percentiles in last observed minute.
MinuteUsage Usage `json:"minute_usage"`
// Percentile in last hour.
HourUsage Usage `json:"hour_usage"`
// Percentile in last day.
DayUsage Usage `json:"day_usage"`
}
99 changes: 99 additions & 0 deletions info/v2/container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 v2

import (
"time"
)

type CpuSpec struct {
// Requested cpu shares. Default is 1024.
Limit uint64 `json:"limit"`
// Requested cpu hard limit. Default is unlimited (0).
// Units: milli-cpus.
MaxLimit uint64 `json:"max_limit"`
// Cpu affinity mask.
// TODO(rjnagal): Add a library to convert mask string to set of cpu bitmask.
Mask string `json:"mask,omitempty"`
}

type MemorySpec struct {
// The amount of memory requested. Default is unlimited (-1).
// Units: bytes.
Limit uint64 `json:"limit,omitempty"`

// The amount of guaranteed memory. Default is 0.
// Units: bytes.
Reservation uint64 `json:"reservation,omitempty"`

// The amount of swap space requested. Default is unlimited (-1).
// Units: bytes.
SwapLimit uint64 `json:"swap_limit,omitempty"`
}

type ContainerSpec struct {
// Time at which the container was created.
CreationTime time.Time `json:"creation_time,omitempty"`

HasCpu bool `json:"has_cpu"`
Cpu CpuSpec `json:"cpu,omitempty"`

HasMemory bool `json:"has_memory"`
Memory MemorySpec `json:"memory,omitempty"`
}

type Percentiles struct {
// Indicates whether the stats are present or not.
// If true, values below do not have any data.
Present bool `json:"present"`
// Average over the collected sample.
Mean uint64 `json:"mean"`
// Max seen over the collected sample.
Max uint64 `json:"max"`
// 90th percentile over the collected sample.
Ninety uint64 `json:"ninety"`
}

type Usage struct {
// Indicates amount of data available [0-100].
// If we have data for half a day, we'll still process DayUsage,
// but set PercentComplete to 50.
PercentComplete int32 `json:"percent_complete"`
// Mean, Max, and 90p cpu rate value in milliCpus/seconds. Converted to milliCpus to avoid floats.
Cpu Percentiles `json:"cpu"`
// Mean, Max, and 90p memory size in bytes.
Memory Percentiles `json:"memory"`
}

// latest sample collected for a container.
type InstantUsage struct {
// cpu rate in cpu milliseconds/second.
Cpu uint64 `json:"cpu"`
// Memory usage in bytes.
Memory uint64 `json:"memory"`
}

type DerivedStats struct {
// Time of generation of these stats.
Timestamp time.Time `json:"timestamp"`
// Latest instantaneous sample.
LatestUsage InstantUsage `json:"latest_usage"`
// Percentiles in last observed minute.
MinuteUsage Usage `json:"minute_usage"`
// Percentile in last hour.
HourUsage Usage `json:"hour_usage"`
// Percentile in last day.
DayUsage Usage `json:"day_usage"`
}
5 changes: 3 additions & 2 deletions manager/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/golang/glog"
"github.com/google/cadvisor/container"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v2"
"github.com/google/cadvisor/storage/memory"
"github.com/google/cadvisor/summary"
"github.com/google/cadvisor/utils/cpuload"
Expand Down Expand Up @@ -101,9 +102,9 @@ func (c *containerData) GetInfo() (*containerInfo, error) {
return &c.info, nil
}

func (c *containerData) DerivedStats() (info.DerivedStats, error) {
func (c *containerData) DerivedStats() (v2.DerivedStats, error) {
if c.summaryReader == nil {
return info.DerivedStats{}, fmt.Errorf("derived stats not enabled for container %q", c.info.Name)
return v2.DerivedStats{}, fmt.Errorf("derived stats not enabled for container %q", c.info.Name)
}
return c.summaryReader.DerivedStats()
}
Expand Down
7 changes: 4 additions & 3 deletions manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/events"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v2"
"github.com/google/cadvisor/storage/memory"
"github.com/google/cadvisor/utils/cpuload"
"github.com/google/cadvisor/utils/oomparser"
Expand Down Expand Up @@ -65,7 +66,7 @@ type Manager interface {
GetContainerSpec(containerName string) (info.ContainerSpec, error)

// Get derived stats for a container.
GetContainerDerivedStats(containerName string) (info.DerivedStats, error)
GetContainerDerivedStats(containerName string) (v2.DerivedStats, error)

// Get information about the machine.
GetMachineInfo() (*info.MachineInfo, error)
Expand Down Expand Up @@ -424,7 +425,7 @@ func (self *manager) containerDataSliceToContainerInfoSlice(containers []*contai
return output, nil
}

func (self *manager) GetContainerDerivedStats(containerName string) (info.DerivedStats, error) {
func (self *manager) GetContainerDerivedStats(containerName string) (v2.DerivedStats, error) {
var ok bool
var cont *containerData
func() {
Expand All @@ -433,7 +434,7 @@ func (self *manager) GetContainerDerivedStats(containerName string) (info.Derive
cont, ok = self.containers[namespacedContainerName{Name: containerName}]
}()
if !ok {
return info.DerivedStats{}, fmt.Errorf("unknown container %q", containerName)
return v2.DerivedStats{}, fmt.Errorf("unknown container %q", containerName)
}
return cont.DerivedStats()
}
Expand Down
5 changes: 3 additions & 2 deletions manager/manager_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package manager
import (
"github.com/google/cadvisor/events"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v2"
"github.com/stretchr/testify/mock"
)

Expand Down Expand Up @@ -59,9 +60,9 @@ func (c *ManagerMock) GetContainerSpec(containerName string) (info.ContainerSpec
return args.Get(0).(info.ContainerSpec), args.Error(1)
}

func (c *ManagerMock) GetContainerDerivedStats(containerName string) (info.DerivedStats, error) {
func (c *ManagerMock) GetContainerDerivedStats(containerName string) (v2.DerivedStats, error) {
args := c.Called(containerName)
return args.Get(0).(info.DerivedStats), args.Error(1)
return args.Get(0).(v2.DerivedStats), args.Error(1)
}

func (c *ManagerMock) WatchForEvents(queryuest *events.Request, passedChannel chan *events.Event) error {
Expand Down
2 changes: 1 addition & 1 deletion summary/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package summary

import (
info "github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)

// Manages a buffer of usage samples.
Expand Down
2 changes: 1 addition & 1 deletion summary/buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"reflect"
"testing"

info "github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)

func createSample(i uint64) info.Usage {
Expand Down
2 changes: 1 addition & 1 deletion summary/percentiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"sort"

"github.com/golang/glog"
info "github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)

const secondsToMilliSeconds = 1000
Expand Down
2 changes: 1 addition & 1 deletion summary/percentiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"testing"
"time"

info "github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)

const Nanosecond = 1000000000
Expand Down
7 changes: 4 additions & 3 deletions summary/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import (
"sync"
"time"

info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)

// Usage fields we track for generating percentiles.
Expand Down Expand Up @@ -56,7 +57,7 @@ type StatsSummary struct {
// Adds a new seconds sample.
// If enough seconds samples are collected, a minute sample is generated and derived
// stats are updated.
func (s *StatsSummary) AddSample(stat info.ContainerStats) error {
func (s *StatsSummary) AddSample(stat v1.ContainerStats) error {
sample := secondSample{}
sample.Timestamp = stat.Timestamp
if s.available.Cpu {
Expand Down Expand Up @@ -168,7 +169,7 @@ func (s *StatsSummary) DerivedStats() (info.DerivedStats, error) {
return s.derivedStats, nil
}

func New(spec info.ContainerSpec) (*StatsSummary, error) {
func New(spec v1.ContainerSpec) (*StatsSummary, error) {
summary := StatsSummary{}
if spec.HasCpu {
summary.available.Cpu = true
Expand Down

0 comments on commit d3db850

Please sign in to comment.