1 # Copyright (c) 2021 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 """BPF performance bundle."""
16 from logging import getLogger
24 Creates a BPF object. This is the main object for defining a BPF program,
25 and interacting with its output.
27 Syntax: BPF({text=BPF_program | src_file=filename}
28 [, usdt_contexts=[USDT_object, ...]]
29 [, cflags=[arg1, ...]] [, debug=int]
32 Exactly one of text or src_file must be supplied (not both).
34 def __init__(self, program, serializer, hook):
35 """Initialize Bundle BPF Perf event class.
37 :param program: BPF C code.
38 :param serializer: Metric serializer.
39 :param hook: Process ID.
41 :type serializer: Serializer
45 self.code = program[u"code"]
46 self.metrics = program[u"metrics"]
47 self.events = program[u"events"]
48 self.api_replies_list = list()
49 self.serializer = serializer
52 self.obj = BPF(text=self.code)
54 def attach(self, duration):
58 :param duration: Trial duration.
62 for event in self.events:
63 self.obj.attach_perf_event(
64 ev_type=event[u"type"],
65 ev_config=event[u"name"],
66 fn_name=event[u"target"],
67 sample_period=duration
69 except AttributeError:
70 getLogger(__name__).error(u"Cannot attach BPF events!")
75 Dettach events from BPF.
78 for event in self.events:
79 self.obj.detach_perf_event(
80 ev_type=event[u"type"],
81 ev_config=event[u"name"]
83 except AttributeError:
84 getLogger(__name__).error(u"Cannot dettach BPF events!")
89 Fetch data by invoking API calls to BPF.
91 self.serializer.create(metrics=self.metrics)
92 for _, metric_list in self.metrics.items():
93 for metric in metric_list:
94 for (key, val) in self.obj.get_table(metric[u"name"]).items():
97 item[u"name"] = metric[u"name"]
98 item[u"value"] = val.value
99 for label in metric[u"labels"]:
100 labels[label] = getattr(key, label)
101 item[u"labels"] = labels
102 self.api_replies_list.append(item)
103 getLogger(__name__).info(item)
105 def process_data(self):
107 Post process API replies.
109 for item in self.api_replies_list:
110 self.serializer.serialize(
111 metric=item[u"name"], labels=item[u"labels"], item=item