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.
53 EventCode, UMask, EdgeDetect, AnyThread, Invert, CounterMask
56 self.serializer.create(metrics=self.metrics)
57 for event in self.events:
58 text = subprocess.getoutput(
59 f"""sudo perf stat -x\; -e\
60 '{{cpu/event={hex(event[u"EventCode"])},\
61 umask={hex(event[u"UMask"])}/u}}'\
67 getLogger("console_stdout").info(event[u"name"])
70 getLogger("console_stdout").info(
71 f"Could not get counters for event \"{event[u'name']}\""
72 f". Is it supported by CPU?"
76 for line in text.splitlines():
79 item[u"name"] = event[u"name"]
80 item[u"value"] = line.split(";")[1]
81 labels["thread"] = u"-".join(
82 line.split(";")[0].split("-")[0:-1]
84 labels["pid"] = line.split(";")[0].split("-")[-1]
85 labels["name"] = item[u"name"]
86 item[u"labels"] = labels
88 getLogger("console_stdout").info(item)
89 self.api_replies_list.append(item)
91 except AttributeError:
92 getLogger("console_stderr").error(f"Could not successfully run "
93 f"perf stat command.")
94 sys.exit(Constants.err_linux_perf_stat)
102 def process_data(self):
104 Post process API replies.
106 for item in self.api_replies_list:
107 self.serializer.serialize(
108 metric=item[u"name"], labels=item[u"labels"], item=item