// Updates the default registry. func (sr StatsReporter) updateStats() { // Stats for host. sr.updateHostStats() // Stats for the containers. var running []dao.RunningService running, err := zkservice.LoadRunningServicesByHost(sr.conn, sr.hostID) if err != nil { glog.Errorf("updateStats: zkservice.LoadRunningServicesByHost (conn: %+v hostID: %v) failed: %v", sr.conn, sr.hostID, err) } for _, rs := range running { if rs.DockerID != "" { containerRegistry := sr.getOrCreateContainerRegistry(rs.ServiceID, rs.InstanceID) if cpuacctStat, err := cgroup.ReadCpuacctStat(cgroup.GetCgroupDockerStatsFilePath(rs.DockerID, cgroup.Cpuacct)); err != nil { glog.V(4).Infof("Couldn't read CpuacctStat:", err) } else { metrics.GetOrRegisterGauge("cgroup.cpuacct.system", containerRegistry).Update(cpuacctStat.System) metrics.GetOrRegisterGauge("cgroup.cpuacct.user", containerRegistry).Update(cpuacctStat.User) } if memoryStat, err := cgroup.ReadMemoryStat(cgroup.GetCgroupDockerStatsFilePath(rs.DockerID, cgroup.Memory)); err != nil { glog.V(4).Infof("Couldn't read MemoryStat:", err) } else { metrics.GetOrRegisterGauge("cgroup.memory.pgmajfault", containerRegistry).Update(memoryStat.Pgfault) metrics.GetOrRegisterGauge("cgroup.memory.totalrss", containerRegistry).Update(memoryStat.TotalRss) metrics.GetOrRegisterGauge("cgroup.memory.cache", containerRegistry).Update(memoryStat.Cache) } } else { glog.V(4).Infof("Skipping stats update for %s (%s), no container ID exists yet", rs.Name, rs.ServiceID) } } // Clean out old container registries sr.removeStaleRegistries(&running) }
func (svc *IService) stats(halt <-chan struct{}) { registry := metrics.NewRegistry() tc := time.Tick(10 * time.Second) for { select { case <-halt: glog.Infof("stop collecting stats for %s", svc.Name) return case t := <-tc: ctr, err := docker.FindContainer(svc.name()) if err != nil { glog.Warningf("Could not find container for isvc %s: %s", svc.Name, err) break } if cpuacctStat, err := cgroup.ReadCpuacctStat(cgroup.GetCgroupDockerStatsFilePath(ctr.ID, cgroup.Cpuacct)); err != nil { glog.Warningf("Could not read CpuacctStat for isvc %s: %s", svc.Name, err) break } else { metrics.GetOrRegisterGauge("CpuacctStat.system", registry).Update(cpuacctStat.System) metrics.GetOrRegisterGauge("CpuacctStat.user", registry).Update(cpuacctStat.User) } if memoryStat, err := cgroup.ReadMemoryStat(cgroup.GetCgroupDockerStatsFilePath(ctr.ID, cgroup.Memory)); err != nil { glog.Warningf("Could not read MemoryStat for isvc %s: %s", svc.Name, err) break } else { metrics.GetOrRegisterGauge("cgroup.memory.pgmajfault", registry).Update(memoryStat.Pgfault) metrics.GetOrRegisterGauge("cgroup.memory.totalrss", registry).Update(memoryStat.TotalRss) metrics.GetOrRegisterGauge("cgroup.memory.cache", registry).Update(memoryStat.Cache) } // Gather the stats stats := []containerStat{} registry.Each(func(name string, i interface{}) { if metric, ok := i.(metrics.Gauge); ok { tagmap := make(map[string]string) tagmap["isvcname"] = svc.Name stats = append(stats, containerStat{name, strconv.FormatInt(metric.Value(), 10), t.Unix(), tagmap}) } if metricf64, ok := i.(metrics.GaugeFloat64); ok { tagmap := make(map[string]string) tagmap["isvcname"] = svc.Name stats = append(stats, containerStat{name, strconv.FormatFloat(metricf64.Value(), 'f', -1, 32), t.Unix(), tagmap}) } }) // Post the stats. data, err := json.Marshal(stats) if err != nil { glog.Warningf("Error marshalling isvc stats json.") break } req, err := http.NewRequest("POST", "http://127.0.0.1:4242/api/put", bytes.NewBuffer(data)) if err != nil { glog.Warningf("Error creating isvc stats request.") break } resp, err := http.DefaultClient.Do(req) if err != nil { glog.V(4).Infof("Error making isvc stats request.") break } if strings.Contains(resp.Status, "204 No Content") == false { glog.Warningf("Couldn't post stats:", resp.Status) break } } } }