1 # Copyright (c) 2022 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Perf Stat performance bundle."""
16 from logging import getLogger
20 from .constants import Constants
25 Creates a Perf stat object. This is the main object for defining a Perf Stat
26 program and interacting with its output.
28 Syntax: perf stat [-e <EVENT> | --event=EVENT] [-a] — <command> [<options>]
30 def __init__(self, program, serializer, hook):
31 """Initialize Bundle Perf Stat event class.
33 :param program: events
34 :param serializer: Metric serializer.
35 :param hook: Process ID.
37 :type serializer: Serializer
40 self.metrics = program[u"metrics"]
41 self.events = program[u"events"]
42 self.api_replies_list = list()
43 self.serializer = serializer
46 def attach(self, duration=1):
50 :param duration: Time how long perf stat is collecting data (in
51 seconds). Default value is 1 second.
55 self.serializer.create(metrics=self.metrics)
56 event = self.events[0]
57 text = subprocess.getoutput(
58 f"""sudo perf stat -x\; -e\
59 '{{cpu/event={hex(event[u"eventcode"])},\
60 umask={hex(event[u"umask"])}/u}}'\
64 except subprocess.CalledProcessError:
65 getLogger("console_stderr").error(f"Could not successfully run "
66 f"perf stat command.")
67 sys.exit(Constants.err_linux_perf_stat)
70 getLogger("console_stdout").info(event[u"eventcode"])
71 elif text.count(u";") < 6:
72 getLogger("console_stdout").info(
73 f"Could not get counters for event "\
74 f"{event[u'eventcode']}. "\
75 f"Is it supported by CPU?"
78 for line in text.splitlines():
81 item[u"name"] = self.metrics['counter'][0]['name']
82 item[u"value"] = line.split(";")[1]
83 labels["thread"] = u"-".join(
84 line.split(";")[0].split("-")[0:-1]
86 labels["pid"] = line.split(";")[0].split("-")[-1]
87 item[u"labels"] = labels
89 getLogger("console_stdout").info(item)
90 self.api_replies_list.append(item)
99 def process_data(self):
101 Post process API replies.
103 for item in self.api_replies_list:
104 self.serializer.serialize(
105 metric=item[u"name"], labels=item[u"labels"], item=item