110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
from analysis import util
|
|
from . import Analyzer, LogSettings, Result, ResultStore
|
|
|
|
log: logging.Logger = logging.getLogger(__name__)
|
|
ONE_DAY = 24 * 60 * 60 * 1000
|
|
MIN_DURATION = 5 * 60 * 1000
|
|
|
|
def init_filter(settings: LogSettings, state: str) -> callable:
|
|
# this implies OR for lists; AND for dicts
|
|
if type(settings.sequences[state]) in (str, list):
|
|
return lambda entry: entry[settings.type_field] in settings.sequences[state]
|
|
else:
|
|
return lambda entry: util.combinate(settings.sequences[state], entry)
|
|
|
|
|
|
class LocomotionActionAnalyzer(Analyzer):
|
|
"""
|
|
calculate locomotion/action times and ratio
|
|
|
|
Anything between LogEntryCache and CacheEnableAction
|
|
is counted as ActionTime, the rest as LocomotionTime.
|
|
"""
|
|
__name__ = "LocomotionAction"
|
|
|
|
limit = ONE_DAY
|
|
|
|
def process(self, entry: dict) -> bool:
|
|
self.last_timestamp = entry["timestamp"]
|
|
if self.instance_start is None:
|
|
self.instance_start = self.last_timestamp
|
|
self.last = self.last_timestamp
|
|
if self.cache_time is None:
|
|
self.cache_time = self.last_timestamp
|
|
offset = self.last_timestamp - self.cache_time
|
|
|
|
if self.current_cache is None and self.filter_start(entry):
|
|
if entry['cache'] is None:
|
|
return False
|
|
self.current_cache = entry['cache']['@id']
|
|
self.cache_time = self.last_timestamp
|
|
self.locomotion.append(offset)
|
|
self.last = None
|
|
elif self.current_cache and self.filter_end(entry):
|
|
self.actions.append(offset)
|
|
self.cache_time = self.last_timestamp
|
|
self.current_cache = None
|
|
self.last = None
|
|
|
|
def result(self, store: ResultStore) -> None:
|
|
if self.last is not None:
|
|
if self.current_cache is None:
|
|
self.locomotion.append(self.last - self.cache_time)
|
|
else:
|
|
self.actions.append(self.last - self.cache_time)
|
|
self.last = None
|
|
locomotion = sum(self.locomotion)
|
|
action = sum(self.actions)
|
|
if not action > 0:
|
|
action = 1
|
|
total = locomotion + action
|
|
if total > self.limit:
|
|
log.error("total duration over limit, skip")
|
|
elif total < MIN_DURATION:
|
|
log.error("total duration too short, skip")
|
|
elif action < MIN_DURATION:
|
|
log.error("action time too short, skip")
|
|
else:
|
|
store.add(Result(type(self), {
|
|
'locomotion_sum': locomotion/1000,
|
|
'action_sum': action/1000,
|
|
'locomotion': self.locomotion,
|
|
'action': self.actions,
|
|
'duration': (self.last_timestamp - self.instance_start)/1000,
|
|
'locomotion_relative': locomotion / total,
|
|
'action_relative': action / total,
|
|
'locomotion_action_ratio': locomotion / action,
|
|
}))
|
|
|
|
def __init__(self, settings: LogSettings):
|
|
super().__init__(settings)
|
|
self.filter_start = init_filter(settings, "start")
|
|
self.filter_end = init_filter(settings, "end")
|
|
self.current_cache = None
|
|
self.cache_time = None
|
|
self.locomotion = []
|
|
self.actions = []
|
|
self.instance_start = None
|
|
self.last_timestamp = None
|
|
self.last = None
|
|
|
|
|
|
class CacheSequenceAnalyzer(Analyzer):
|
|
__name__ = "CacheSequence"
|
|
|
|
def process(self, entry: dict) -> bool:
|
|
if self.filter(entry):
|
|
if entry['cache']:
|
|
self.store.append((entry['timestamp'], entry['cache']['@id']))
|
|
else:
|
|
self.store.append((entry['timestamp'], entry['cache']))
|
|
return False
|
|
|
|
def result(self, store: ResultStore) -> None:
|
|
store.add(Result(type(self), list(self.store)))
|
|
|
|
def __init__(self, settings: LogSettings):
|
|
super().__init__(settings)
|
|
self.store = []
|
|
self.filter = init_filter(settings, "start")
|