Package org.apache.flink.runtime.profiling.impl

Source Code of org.apache.flink.runtime.profiling.impl.InstanceProfiler

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.flink.runtime.profiling.impl;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.flink.runtime.instance.InstanceConnectionInfo;
import org.apache.flink.runtime.profiling.ProfilingException;
import org.apache.flink.runtime.profiling.impl.types.InternalInstanceProfilingData;
import org.apache.flink.util.StringUtils;

public class InstanceProfiler {

  static final String PROC_MEMINFO = "/proc/meminfo";

  static final String PROC_STAT = "/proc/stat";

  static final String PROC_NET_DEV = "/proc/net/dev";

  private static final String LOOPBACK_INTERFACE_NAME = "lo";

  private static final Pattern CPU_PATTERN = Pattern
    .compile("^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).+$");

  private static final Pattern NETWORK_PATTERN = Pattern
    .compile("^\\s*(\\w+):\\s*(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+(\\d+).+$");

  private static final Pattern MEMORY_PATTERN = Pattern.compile("^\\w+:\\s*(\\d+)\\s+kB$");

  private static final int PERCENT = 100;

  private final InstanceConnectionInfo instanceConnectionInfo;

  private long lastTimestamp = 0;

  // CPU related variables
  private long lastCpuUser = 0;

  private long lastCpuNice = 0;

  private long lastCpuSys = 0;

  private long lastCpuIdle = 0;

  private long lastCpuIOWait = 0;

  private long lastCpuIrq = 0;

  private long lastCpuSoftirq = 0;

  // Network related variables
  private long lastReceivedBytes = 0;

  private long lastTramsmittedBytes = 0;

  private long firstTimestamp;

  public InstanceProfiler(InstanceConnectionInfo instanceConnectionInfo)
                                      throws ProfilingException {

    this.instanceConnectionInfo = instanceConnectionInfo;
    this.firstTimestamp = System.currentTimeMillis();
    // Initialize counters by calling generateProfilingData once and ignore the return value
    generateProfilingData(this.firstTimestamp);
  }

  InternalInstanceProfilingData generateProfilingData(long timestamp) throws ProfilingException {

    final long profilingInterval = timestamp - lastTimestamp;

    final InternalInstanceProfilingData profilingData = new InternalInstanceProfilingData(
      this.instanceConnectionInfo, (int) profilingInterval);

    updateCPUUtilization(profilingData);
    updateMemoryUtilization(profilingData);
    updateNetworkUtilization(profilingData);

    // Update timestamp
    this.lastTimestamp = timestamp;

    return profilingData;
  }

  private void updateMemoryUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {

    BufferedReader in = null;

    try {

      in = new BufferedReader(new FileReader(PROC_MEMINFO));

      long freeMemory = 0;
      long totalMemory = 0;
      long bufferedMemory = 0;
      long cachedMemory = 0;
      long cachedSwapMemory = 0;

      int count = 0;
      String output;
      while ((output = in.readLine()) != null) {

        switch (count) {
        case 0: // Total memory
          totalMemory = extractMemoryValue(output);
          break;
        case 1: // Free memory
          freeMemory = extractMemoryValue(output);
          break;
        case 2: // Buffers
          bufferedMemory = extractMemoryValue(output);
          break;
        case 3: // Cache
          cachedMemory = extractMemoryValue(output);
          break;
        case 4:
          cachedSwapMemory = extractMemoryValue(output);
          break;
        default:
          break;
        }

        ++count;
      }

      profilingData.setTotalMemory(totalMemory);
      profilingData.setFreeMemory(freeMemory);
      profilingData.setBufferedMemory(bufferedMemory);
      profilingData.setCachedMemory(cachedMemory);
      profilingData.setCachedSwapMemory(cachedSwapMemory);

    } catch (IOException ioe) {
      throw new ProfilingException("Error while reading network utilization: "
        + StringUtils.stringifyException(ioe));
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
        }
      }
    }

  }

  private long extractMemoryValue(String line) throws ProfilingException {

    final Matcher matcher = MEMORY_PATTERN.matcher(line);
    if (!matcher.matches()) {
      throw new ProfilingException("Cannot extract memory data for profiling from line " + line);
    }

    return Long.parseLong(matcher.group(1));
  }

  private void updateNetworkUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {

    BufferedReader in = null;

    try {

      in = new BufferedReader(new FileReader(PROC_NET_DEV));

      long receivedSum = 0;
      long transmittedSum = 0;

      String output;
      while ((output = in.readLine()) != null) {
        final Matcher networkMatcher = NETWORK_PATTERN.matcher(output);
        if (!networkMatcher.matches()) {
          continue;
        }
        /*
         * Extract information according to
         * http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
         */

        if (LOOPBACK_INTERFACE_NAME.equals(networkMatcher.group(1))) {
          continue;
        }

        receivedSum += Long.parseLong(networkMatcher.group(2));
        transmittedSum += Long.parseLong(networkMatcher.group(3));
      }

      in.close();
      in = null;

      profilingData.setReceivedBytes(receivedSum - this.lastReceivedBytes);
      profilingData.setTransmittedBytes(transmittedSum - this.lastTramsmittedBytes);

      // Store values for next call
      this.lastReceivedBytes = receivedSum;
      this.lastTramsmittedBytes = transmittedSum;

    } catch (IOException ioe) {
      throw new ProfilingException("Error while reading network utilization: "
        + StringUtils.stringifyException(ioe));
    } catch (NumberFormatException nfe) {
      throw new ProfilingException("Error while reading network utilization: "
        + StringUtils.stringifyException(nfe));
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
        }
      }
    }
  }

  private void updateCPUUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {

    BufferedReader in = null;

    try {

      in = new BufferedReader(new FileReader(PROC_STAT));
      final String output = in.readLine();
      if (output == null) {
        throw new ProfilingException("Cannot read CPU utilization, return value is null");
      }

      in.close();
      in = null;

      final Matcher cpuMatcher = CPU_PATTERN.matcher(output);
      if (!cpuMatcher.matches()) {
        throw new ProfilingException("Cannot extract CPU utilization from output \"" + output + "\"");
      }

      /*
       * Extract the information from the read line according to
       * http://www.linuxhowtos.org/System/procstat.htm
       */

      final long cpuUser = Long.parseLong(cpuMatcher.group(1));
      final long cpuNice = Long.parseLong(cpuMatcher.group(2));
      final long cpuSys = Long.parseLong(cpuMatcher.group(3));
      final long cpuIdle = Long.parseLong(cpuMatcher.group(4));
      final long cpuIOWait = Long.parseLong(cpuMatcher.group(5));
      final long cpuIrq = Long.parseLong(cpuMatcher.group(6));
      final long cpuSoftirq = Long.parseLong(cpuMatcher.group(7));

      // Calculate deltas
      final long deltaCpuUser = cpuUser - this.lastCpuUser;
      final long deltaCpuNice = cpuNice - this.lastCpuNice;
      final long deltaCpuSys = cpuSys - this.lastCpuSys;
      final long deltaCpuIdle = cpuIdle - this.lastCpuIdle;
      final long deltaCpuIOWait = cpuIOWait - this.lastCpuIOWait;
      final long deltaCpuIrq = cpuIrq - this.lastCpuIrq;
      final long deltaCpuSoftirq = cpuSoftirq - this.lastCpuSoftirq;
      final long deltaSum = deltaCpuUser + deltaCpuNice + deltaCpuSys + deltaCpuIdle + deltaCpuIOWait
        + deltaCpuIrq + deltaCpuSoftirq;

      // TODO: Fix deltaSum = 0 situation

      // Set the percentage values for the profiling data object
      /*
       * profilingData.setIdleCPU((int)((deltaCpuIdle*PERCENT)/deltaSum));
       * profilingData.setUserCPU((int)((deltaCpuUser*PERCENT)/deltaSum));
       * profilingData.setSystemCPU((int)((deltaCpuSys*PERCENT)/deltaSum));
       * profilingData.setIoWaitCPU((int)((deltaCpuIOWait*PERCENT)/deltaSum));
       * profilingData.setHardIrqCPU((int)((deltaCpuIrq*PERCENT)/deltaSum));
       * profilingData.setSoftIrqCPU((int)((deltaCpuSoftirq*PERCENT)/deltaSum));
       */
      // TODO: bad quick fix
      if (deltaSum > 0) {
        profilingData.setIdleCPU((int) ((deltaCpuIdle * PERCENT) / deltaSum));
        profilingData.setUserCPU((int) ((deltaCpuUser * PERCENT) / deltaSum));
        profilingData.setSystemCPU((int) ((deltaCpuSys * PERCENT) / deltaSum));
        profilingData.setIoWaitCPU((int) ((deltaCpuIOWait * PERCENT) / deltaSum));
        profilingData.setHardIrqCPU((int) ((deltaCpuIrq * PERCENT) / deltaSum));
        profilingData.setSoftIrqCPU((int) ((deltaCpuSoftirq * PERCENT) / deltaSum));
      } else {
        profilingData.setIdleCPU((int) (deltaCpuIdle));
        profilingData.setUserCPU((int) (deltaCpuUser));
        profilingData.setSystemCPU((int) (deltaCpuSys));
        profilingData.setIoWaitCPU((int) (deltaCpuIOWait));
        profilingData.setHardIrqCPU((int) (deltaCpuIrq));
        profilingData.setSoftIrqCPU((int) (deltaCpuSoftirq));
      }
      // Store values for next call
      this.lastCpuUser = cpuUser;
      this.lastCpuNice = cpuNice;
      this.lastCpuSys = cpuSys;
      this.lastCpuIdle = cpuIdle;
      this.lastCpuIOWait = cpuIOWait;
      this.lastCpuIrq = cpuIrq;
      this.lastCpuSoftirq = cpuSoftirq;

    } catch (IOException ioe) {
      throw new ProfilingException("Error while reading CPU utilization: " + StringUtils.stringifyException(ioe));
    } catch (NumberFormatException nfe) {
      throw new ProfilingException("Error while reading CPU utilization: " + StringUtils.stringifyException(nfe));
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
        }
      }
    }

  }

  /**
   * @return InternalInstanceProfilingData ProfilingData for the instance from execution-start to currentTime
   * @throws ProfilingException
   */
  public InternalInstanceProfilingData generateCheckpointProfilingData() throws ProfilingException {
    final long profilingInterval = System.currentTimeMillis() - this.firstTimestamp;

    final InternalInstanceProfilingData profilingData = new InternalInstanceProfilingData(
      this.instanceConnectionInfo, (int) profilingInterval);

    updateCPUUtilization(profilingData);
    updateMemoryUtilization(profilingData);
    updateNetworkUtilization(profilingData);

    return profilingData;
  }
}
TOP

Related Classes of org.apache.flink.runtime.profiling.impl.InstanceProfiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.