--- /dev/null
+Linux automaton
+===============
+
+README about this Python package.
--- /dev/null
+__version__ = '0.0.1'
--- /dev/null
+from .net import NetStateProvider
+
+
+class State:
+ def __init__(self):
+ self.hello = 23
+
+ def _incr_hello(self):
+ self.hello += 5
+
+
+class Automaton:
+ def __init__(self):
+ self._state = State()
+ self._state_providers = [
+ NetStateProvider(self._state),
+ ]
+
+ def process_event(self, ev):
+ for sp in self._state_providers:
+ sp.process_event(ev)
+
+ @property
+ def state(self):
+ return self._state
--- /dev/null
+from linuxautomaton import sp
+
+
+class NetStateProvider(sp.StateProvider):
+ def __init__(self, state):
+ self._state = state
+ cbs = {
+ 'hello': self._process_hello_event,
+ }
+
+ self._register_cbs(cbs)
+
+ def process_event(self, ev):
+ self._process_event_cb(ev)
+
+ def _process_hello_event(self, ev):
+ if ev.cond:
+ self._state._incr_hello()
--- /dev/null
+class StateProvider:
+ def process_event(self, ev):
+ raise NotImplementedError()
+
+ def _register_cbs(self, cbs):
+ self._cbs = cbs
+
+ def _process_event_cb(self, ev):
+ name = ev.name
+
+ if name in self._cbs:
+ self._cbs[name](ev)
--- /dev/null
+#!/usr/bin/env python3
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 Philippe Proulx <eepp.ca>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from setuptools import setup
+import sys
+
+
+# make sure we run Python 3+ here
+v = sys.version_info
+if v.major < 3:
+ sys.stderr.write('Sorry, linuxautomaton needs Python 3\n')
+ sys.exit(1)
+
+packages = [
+ 'linuxautomaton',
+]
+
+import linuxautomaton
+
+setup(name='linuxautomaton',
+ version=linuxautomaton.__version__,
+ description='Linux kernel finite state machine with trace events '
+ 'as inputs',
+ author='Julien Desfossez',
+ author_email='jdesfossez@efficios.com',
+ url='https://github.com/jdesfossez/lttng-analyses',
+ packages=packages)
--- /dev/null
+LTTng analyses command line interfaces
+======================================
+
+README about this Python package.
--- /dev/null
+__version__ = '0.0.1'
--- /dev/null
+class Analysis:
+ def process_event(self, ev):
+ raise NotImplementedError()
--- /dev/null
+from .analysis import Analysis
+
+
+class Iotop(Analysis):
+ def __init__(self, state, split, split_count):
+ self._state = state
+ self._split = split
+ self._split_count = split_count
+ self._ev_count = 0
+ self._tmp_ev_count = 0
+ self._buckets = []
+ self._last_reset_hello = state.hello
+
+ if not self._split:
+ self._buckets.append(0)
+
+ def process_event(self, ev):
+ self._ev_count += 1
+ self._tmp_ev_count += 1
+
+ if self._split:
+ if self._tmp_ev_count == self._split_count:
+ self._tmp_ev_count = 0
+ cur_hello_diff = self._state.hello - self._last_reset_hello
+ self._last_reset_hello = self._state.hello
+ self._buckets.append(cur_hello_diff)
+ else:
+ self._buckets[0] = self._state.hello
+
+ @property
+ def buckets(self):
+ return self._buckets
+
+ @property
+ def event_count(self):
+ return self._ev_count
--- /dev/null
+#!/usr/bin/env python3
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 Philippe Proulx <eepp.ca>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from setuptools import setup
+import sys
+
+
+# make sure we run Python 3+ here
+v = sys.version_info
+if v.major < 3:
+ sys.stderr.write('Sorry, lttnganalyses needs Python 3\n')
+ sys.exit(1)
+
+packages = [
+ 'lttnganalyses',
+]
+
+import lttnganalyses
+
+setup(name='lttnganalyses',
+ version=lttnganalyses.__version__,
+ description='LTTng analyses core',
+ author='Julien Desfossez',
+ author_email='jdesfossez@efficios.com',
+ url='https://github.com/jdesfossez/lttng-analyses',
+ packages=packages)
--- /dev/null
+Linux automaton
+===============
+
+README about this Python package.
--- /dev/null
+__version__ = '0.0.1'
--- /dev/null
+import linuxautomaton.automaton
+#import lttnganalysescli
+import argparse
+import sys
+
+
+class Command:
+ def __init__(self, add_arguments_cb, enable_u_opt):
+ self._add_arguments_cb = add_arguments_cb
+ self._enable_u_opt = enable_u_opt
+ self._create_automaton()
+
+ def _error(self, msg, exit_code=1):
+ print(msg, file=sys.stderr)
+ sys.exit(exit_code)
+
+ def _gen_error(self, msg, exit_code=1):
+ self._error('Error: {}'.format(msg), exit_code)
+
+ def _cmdline_error(self, msg, exit_code=1):
+ self._error('Command line error: {}'.format(msg), exit_code)
+
+ def _parse_args(self):
+ ap = argparse.ArgumentParser(description=self._DESC)
+
+ # common arguments
+ ap.add_argument('-b', '--begin', help='begin timestamp')
+ ap.add_argument('-e', '--end', help='end timestamp')
+
+ # optional common argument
+ if self._enable_u_opt:
+ ap.add_argument('-u', '--uuu', help='famous U option')
+
+ # specific arguments
+ self._add_arguments_cb(ap)
+
+ # version of the specific command
+ #version = '%(prog)s v{}'.format(lttnganalysescli.__version__)
+ ap.add_argument('-V', '--version', action='version',
+ version=self._VERSION)
+
+ # parse arguments
+ args = ap.parse_args()
+
+ # common validation
+ if args.begin != 'begin':
+ self._cmdline_error('begin argument should be "begin"')
+
+ if args.end != 'end':
+ self._cmdline_error('end argument should be "end"')
+
+ if self._enable_u_opt:
+ if args.uuu != 'uuu':
+ self._cmdline_error('uuu argument should be "uuu"')
+
+ # transform and save arguments
+ self._arg_begin = len(args.begin)
+ self._arg_end = len(args.end)
+
+ if self._enable_u_opt:
+ self._arg_uuu = len(args.uuu)
+
+ # save all arguments
+ self._args = args
+
+ def _create_automaton(self):
+ self._automaton = linuxautomaton.automaton.Automaton()
--- /dev/null
+from .command import Command
+import lttnganalyses.iotop
+import random
+
+
+class Iotop(Command):
+ _VERSION = '1.2.3'
+ _DESC = """The iotop command blabla bla.
+It also does this and that."""
+
+ def __init__(self):
+ super().__init__(self._add_arguments, True)
+
+ def _validate_transform_args(self):
+ # split?
+ self._arg_split_count = None
+ self._arg_split = self._args.split
+
+ # split count if splitting?
+ if self._arg_split:
+ if self._args.split_count is None:
+ self._cmdline_error('you must specify --split-count '
+ 'with --split')
+ else:
+ self._arg_split_count = self._args.split_count
+
+ # path
+ self._arg_path = self._args.path
+
+ def run(self):
+ # parse arguments first
+ self._parse_args()
+
+ # validate, transform and save specific arguments
+ self._validate_transform_args()
+
+ # everything processed at this point
+ print('begin: {}'.format(self._arg_begin))
+ print('end: {}'.format(self._arg_end))
+ print('uuu: {}'.format(self._arg_uuu))
+ print('split: {}'.format(self._arg_split))
+ print('split-count: {}'.format(self._arg_split_count))
+ print('path: {}'.format(self._arg_path))
+ print('---')
+
+ # create the appropriate analysis/analyses
+ self._create_analysis()
+
+ # run the analysis
+ self._run_analysis()
+
+ # print results
+ self._print_results()
+
+ def _create_analysis(self):
+ self._analysis = lttnganalyses.iotop.Iotop(self._automaton.state,
+ self._arg_split,
+ self._arg_split_count)
+
+ def _run_analysis(self):
+ # event (demo)
+ class Event:
+ def __init__(self):
+ self.cond = bool(random.getrandbits(1))
+ self.name = 'hello'
+
+ # loop of events here
+ for i in range(random.randint(5000, 10000)):
+ ev = Event()
+
+ # feed automaton
+ self._automaton.process_event(ev)
+
+ # feed analysis
+ self._analysis.process_event(ev)
+
+ def _print_results(self):
+ print('event count: {}'.format(self._analysis.event_count))
+ print('buckets:')
+
+ for index, count in enumerate(self._analysis.buckets):
+ print(' {:04d}: {}'.format(index, count))
+
+ def _add_arguments(self, ap):
+ # specific argument
+ ap.add_argument('-s', '--split', action='store_true', help='split')
+ ap.add_argument('-c', '--split-count', type=int, help='split count')
+
+ # could be a common argument too
+ ap.add_argument('path', help='trace path')
+
+
+# entry point
+def run():
+ # create command
+ iotopcmd = Iotop()
+
+ # execute command
+ iotopcmd.run()
--- /dev/null
+#!/usr/bin/env python3
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2014 Philippe Proulx <eepp.ca>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from setuptools import setup
+import sys
+
+
+# make sure we run Python 3+ here
+v = sys.version_info
+if v.major < 3:
+ sys.stderr.write('Sorry, lttnganalysescli needs Python 3\n')
+ sys.exit(1)
+
+packages = [
+ 'lttnganalysescli',
+]
+
+entry_points = {
+ 'console_scripts': [
+ 'iotop = lttnganalysescli.iotop:run'
+ ],
+}
+
+import lttnganalysescli
+
+setup(name='lttnganalysescli',
+ version=lttnganalysescli.__version__,
+ description='LTTng analyses command line interfaces',
+ author='Julien Desfossez',
+ author_email='jdesfossez@efficios.com',
+ url='https://github.com/jdesfossez/lttng-analyses',
+ packages=packages,
+ entry_points=entry_points)