1 # The MIT License (MIT)
3 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 self
.refresh_period
= None
27 self
.period_begin_ev_name
= None
28 self
.period_end_ev_name
= None
29 self
.period_begin_key_fields
= None
30 self
.period_end_key_fields
= None
31 self
.period_key_value
= None
34 self
.min_duration
= None
35 self
.max_duration
= None
44 def __init__(self
, state
, conf
):
47 self
._period
_key
= None
48 self
._period
_start
_ts
= None
49 self
._last
_event
_ts
= None
50 self
._notification
_cbs
= {}
56 def process_event(self
, ev
):
57 self
._check
_analysis
_end
(ev
)
61 self
._last
_event
_ts
= ev
.timestamp
64 if self
._conf
.begin_ts
:
65 self
._check
_analysis
_begin
(ev
)
69 self
._period
_start
_ts
= ev
.timestamp
72 # Prioritise period events over refresh period
73 if self
._conf
.period_begin_ev_name
is not None:
74 self
._handle
_period
_event
(ev
)
75 elif self
._conf
.refresh_period
is not None:
76 self
._check
_refresh
(ev
)
79 raise NotImplementedError()
82 if self
._period
_start
_ts
:
85 def register_notification_cbs(self
, cbs
):
87 if name
not in self
._notification
_cbs
:
88 self
._notification
_cbs
[name
] = []
90 self
._notification
_cbs
[name
].append(cbs
[name
])
92 def _send_notification_cb(self
, name
, **kwargs
):
93 if name
in self
._notification
_cbs
:
94 for cb
in self
._notification
_cbs
[name
]:
97 def _register_cbs(self
, cbs
):
100 def _process_event_cb(self
, ev
):
103 if name
in self
._cbs
:
105 elif 'syscall_entry' in self
._cbs
and \
106 (name
.startswith('sys_') or name
.startswith('syscall_entry_')):
107 self
._cbs
['syscall_entry'](ev
)
108 elif 'syscall_exit' in self
._cbs
and \
109 (name
.startswith('exit_syscall') or
110 name
.startswith('syscall_exit_')):
111 self
._cbs
['syscall_exit'](ev
)
113 def _check_analysis_begin(self
, ev
):
114 if self
._conf
.begin_ts
and ev
.timestamp
>= self
._conf
.begin_ts
:
116 self
._period
_start
_ts
= ev
.timestamp
119 def _check_analysis_end(self
, ev
):
120 if self
._conf
.end_ts
and ev
.timestamp
> self
._conf
.end_ts
:
123 def _check_refresh(self
, ev
):
124 if not self
._period
_start
_ts
:
125 self
._period
_start
_ts
= ev
.timestamp
126 elif ev
.timestamp
>= (self
._period
_start
_ts
+
127 self
._conf
.refresh_period
):
129 self
._period
_start
_ts
= ev
.timestamp
131 def _handle_period_event(self
, ev
):
132 if ev
.name
!= self
._conf
.period_begin_ev_name
and \
133 ev
.name
!= self
._conf
.period_end_ev_name
:
137 period_key
= Analysis
._get
_period
_event
_key
(
138 ev
, self
._conf
.period_end_key_fields
)
141 # There was an error caused by a missing field, ignore
145 if period_key
== self
._period
_key
:
146 if self
._conf
.period_end_ev_name
:
147 if ev
.name
== self
._conf
.period_end_ev_name
:
149 self
._period
_key
= None
150 self
._period
_start
_ts
= None
151 elif ev
.name
== self
._conf
.period_begin_ev_name
:
153 self
._begin
_period
(period_key
, ev
.timestamp
)
154 elif ev
.name
== self
._conf
.period_begin_ev_name
:
155 period_key
= Analysis
._get
_period
_event
_key
(
156 ev
, self
._conf
.period_begin_key_fields
)
161 if self
._conf
.period_key_value
:
162 # Must convert the period key to string for comparison
163 str_period_key
= tuple(map(str, period_key
))
164 if self
._conf
.period_key_value
!= str_period_key
:
167 self
._begin
_period
(period_key
, ev
.timestamp
)
169 def _begin_period(self
, period_key
, timestamp
):
170 self
._period
_key
= period_key
171 self
._period
_start
_ts
= timestamp
174 def _end_period(self
):
175 self
._end
_period
_cb
()
176 self
._send
_notification
_cb
(Analysis
.TICK_CB
,
177 begin_ns
=self
._period
_start
_ts
,
178 end_ns
=self
._last
_event
_ts
)
180 def _end_period_cb(self
):
184 def _get_period_event_key(ev
, key_fields
):
190 for field
in key_fields
:
192 key_values
.append(ev
[field
])
194 # Error: missing field
197 return tuple(key_values
)
199 def _filter_process(self
, proc
):
202 if self
._conf
.proc_list
and proc
.comm
not in self
._conf
.proc_list
:
204 if self
._conf
.tid_list
and proc
.tid
not in self
._conf
.tid_list
:
208 def _filter_cpu(self
, cpu
):
209 return not (self
._conf
.cpu_list
and cpu
not in self
._conf
.cpu_list
)
This page took 0.034723 seconds and 5 git commands to generate.