summaryrefslogtreecommitdiffstats
path: root/glustolibs-io/shared_files/scripts/memory_and_cpu_logger.py
blob: d2ee80d6c5a10c797431f73ac5cf8d706fa86c0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python
#  Copyright (C) 2020 Red Hat, Inc. <http://www.redhat.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along
#  with this program; if not, write to the Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""
A tool to monitor and log memory consumption processes.
"""
from __future__ import print_function

import argparse
import csv
from time import sleep
import subprocess


def run_command(cmd):
    """
    Run command using Popen and return output
    """
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE, shell=True)
    output = ret.stdout.read().decode('utf8').split('\n')[:-1]
    return output


def get_memory_and_cpu_consumption(proc_name):
    """
    Get the memory and cpu consumed by a given process
    """
    # The command gives an output as shown below:
    # [2020-08-07 09:34:48] 16422 0.0 9.99609
    #
    # Where,
    # [2020-08-07 09:34:48] is UTC timestamp.
    # 16422 is the process ID.
    # 0.0 is the CPU usage.
    # 9.99609 is memory consumption in MB.
    cmd = ("ps u -p `pgrep " + proc_name + "` | "
           "awk 'NR>1 && $11~/" + proc_name + "$/{print "
           "strftime(\"[%Y-%d-%m %H:%M:%S]\", "
           "systime(), 1), $2,$3,$6/1024}'")
    memory_and_cpu_consumed = run_command(cmd)
    return memory_and_cpu_consumed


def main():
    """
    Main function of the tool.
    """
    # Setting up command line arguments
    parser = argparse.ArgumentParser(
        description="A tool to log memory usage of a given process"
        )
    parser.add_argument(
        "-p", "--process_name", type=str, dest="process_name", required=True,
        help="Name of process for which cpu and memory is to be logged")
    parser.add_argument(
        "-i", "--interval", type=int, dest="interval", default=60,
        help="Time interval to wait between consecutive logs(Default:60)")
    parser.add_argument(
        "-c", "--count", type=int, dest="count", default=10,
        help="Number of times memory and CPU has to be logged (Default:10)")
    parser.add_argument(
        '-t', '--testname', type=str, dest="testname", required=True,
        help="Test name for which memory is logged")
    args = parser.parse_args()

    # Declare all three parameters
    process_name = args.process_name
    count = args.count
    interval = args.interval

    # Generating CSV file header
    with open('{}.csv'.format(process_name), 'a') as file:
        csv_writer_obj = csv.writer(file)
        csv_writer_obj.writerow([args.testname, '', '', ''])
        csv_writer_obj.writerow([
            'Time stamp', 'Process ID', 'CPU Usage', 'Memory Usage'])

        # Taking memory output for a given
        # number of times
        for counter in range(0, count):
            print("Iteration: {}".format(counter))
            data = get_memory_and_cpu_consumption(process_name)

            # Logging information to csv file
            for line in data:
                info = line.split(" ")
                csv_writer_obj.writerow([" ".join(info[:2]), info[2],
                                         info[3], info[4]])
                sleep(interval)


if __name__ == "__main__":
    main()