All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.metamx.metrics.cgroups.CpuAcct Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017 Metamarkets Group Inc.
 *
 * 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 com.metamx.metrics.cgroups;

import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.metamx.common.RE;
import com.metamx.common.logger.Logger;
import com.metamx.metrics.CgroupUtil;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.stream.LongStream;

public class CpuAcct
{
  private static final Logger LOG = new Logger(CpuAcct.class);
  private static final String CGROUP = "cpuacct";
  private static final String CGROUP_ACCT_FILE = "cpuacct.usage_all";

  // Private because it requires a specific format and cant' take a generic list of strings
  private static CpuAcctMetric parse(final List lines)
  {
    // File has a header. We skip it
    // See src/test/resources/cpuacct.usage_all for an example
    final int ncpus = lines.size() - 1;
    final long[] usrTime = new long[ncpus];
    final long[] sysTime = new long[ncpus];
    for (int i = 1; i < lines.size(); i++) {
      final String[] splits = lines.get(i).split(CgroupUtil.SPACE_MATCH, 3);
      if (splits.length != 3) {
        throw new RE("Error parsing [%s]", lines.get(i));
      }
      final int cpuNum = Integer.parseInt(splits[0]);
      usrTime[cpuNum] = Long.parseLong(splits[1]);
      sysTime[cpuNum] = Long.parseLong(splits[2]);
    }
    return new CpuAcctMetric(usrTime, sysTime);
  }

  private final CgroupDiscoverer cgroupDiscoverer;

  public CpuAcct(CgroupDiscoverer cgroupDiscoverer)
  {
    this.cgroupDiscoverer = cgroupDiscoverer;
  }

  /**
   * Take a snapshot of the existing data.
   *
   * @return A snapshot with the data populated or a snapshot with zero-length arrays for data.
   */
  public CpuAcctMetric snapshot()
  {
    final File cpuacct;
    try {
      cpuacct = new File(
          cgroupDiscoverer.discover(CGROUP).toFile(),
          CGROUP_ACCT_FILE
      );
    }
    catch (RuntimeException re) {
      LOG.error(re, "Unable to fetch snapshot");
      return new CpuAcctMetric(new long[0], new long[0]);
    }
    try {
      return parse(Files.readAllLines(cpuacct.toPath(), Charsets.UTF_8));
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  public static class CpuAcctMetric
  {
    private final long[] usrTimes;
    private final long[] sysTimes;

    CpuAcctMetric(long[] usrTimes, long[] sysTimes)
    {
      Preconditions.checkArgument(usrTimes.length == sysTimes.length, "Lengths must match");
      this.usrTimes = usrTimes;
      this.sysTimes = sysTimes;
    }

    public final int cpuCount()
    {
      return usrTimes.length;
    }

    public final long[] sysTimes()
    {
      return sysTimes;
    }

    public final long[] usrTimes()
    {
      return usrTimes;
    }

    public final long usrTime(int cpuNum)
    {
      return usrTimes[cpuNum];
    }

    public final long sysTime(int cpu_Num)
    {
      return sysTimes[cpu_Num];
    }

    public final long usrTime()
    {
      return LongStream.of(usrTimes).sum();
    }

    public final long sysTime()
    {
      return LongStream.of(sysTimes).sum();
    }

    public final long time()
    {
      return usrTime() + sysTime();
    }

    public final CpuAcctMetric cumulativeSince(CpuAcctMetric other)
    {
      final int cpuCount = cpuCount();
      Preconditions.checkArgument(cpuCount == other.cpuCount(), "Cpu count missmatch");
      final long[] sysTimes = new long[cpuCount];
      final long[] usrTimes = new long[cpuCount];
      for (int i = 0; i < cpuCount; i++) {
        sysTimes[i] = this.sysTimes[i] - other.sysTimes[i];
        usrTimes[i] = this.usrTimes[i] - other.usrTimes[i];
      }
      return new CpuAcctMetric(usrTimes, sysTimes);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy