Beispiel #1
0
    def __init__(self, **kwargs):
        self._special_values = kwargs.pop('special_values', None)
        initial = kwargs.pop('initial', None)
        if (initial is not None and
                self._special_values is None or
                initial not in self._special_values):
            initial_td = parse_timedelta(initial)
            initial_valid = False
        else:
            initial_td = None
            initial_valid = True
        choices = []

        # Rebuild the choices list to ensure that
        # the value is normalized using timedelta_str
        for choice in kwargs.pop('choices'):
            td = None
            if not (isinstance(choice, list) or isinstance(choice, tuple)):
                if (self._special_values is None or
                        choice not in self._special_values):
                    td = parse_timedelta(choice)
                    td_str = timedelta_str(td)
                    value = td_str
                    label = td_str
                else:
                    value = choice
                    label = choice

            else:
                (value, label) = choice
                if (self._special_values is None or
                        value not in self._special_values):
                    td = parse_timedelta(value)
                    value = timedelta_str(td)

            choice = (value, label)
            choices.append(choice)

            if initial_td is not None and initial_td == td:
                initial = value
                initial_valid = True

        kwargs['choices'] = choices
        logger.debug("Choices: %s" % choices)
        if not initial_valid:
            raise KeyError('Initial duration is invalid: %s' % initial)

        super(DurationField, self).__init__(initial=initial, **kwargs)
Beispiel #2
0
 def render(self, name, value, attrs):
     initial_date = attrs.get('initial_date', None)
     if initial_date:
         m = re.match("now *- *(.+)", initial_date)
         if m:
             secs = timedelta_total_seconds(parse_timedelta(m.group(1)))
             initial_date = (
                 "d = new Date(); d.setSeconds(d.getSeconds()-%d);" \
                 % secs)
         else:
             initial_date = "d = '%s';" % initial_date
     else:
         initial_date = "d = new Date();"
     msg = '''
     {0} <span id="datenow_{name}" class="icon-calendar" title="Set date to today"> </span>
     <script type="text/javascript">
           $("#id_{name}").datepicker({{
              format: "mm/dd/YY",
              defaultDate: +2,
              autoclose: true
           }});
           {initial_date}
           $("#id_{name}").datepicker("setDate", d);
           $("#datenow_{name}").click(function() {{ $("#id_{name}").datepicker("setDate", new Date()); }});
       </script>
       '''
     return msg.format(
         super(DateWidget, self).render(name, value, attrs),
         name=name, initial_date=initial_date
     )
Beispiel #3
0
 def render(self, name, value, attrs):
     initial_time = attrs.get('initial_time', None)
     if initial_time:
         m = re.match("now *- *(.+)", initial_time)
         if m:
             secs = timedelta_total_seconds(parse_timedelta(m.group(1)))
             initial_time = (
                 "d = new Date(); d.setSeconds(d.getSeconds()-%d);" \
                 % secs)
         else:
             initial_time = "d = '%s';" % initial_time
     else:
         initial_time = "d = new Date();"
     msg = '''
     {0} <span id="timenow_{name}" class="icon-time" title="Set time/date to now"> </span>
     <script type="text/javascript">
           $("#id_{name}").timepicker({{
              step: 15,
              scrollDefaultNow:true,
              timeFormat:"g:i:s a"
           }});
           $("#timenow_{name}").click(function() {{
              $("#id_{name}").timepicker("setTime", new Date());
           }});
           {initial_time}
           $("#id_{name}").timepicker("setTime", d);
     </script>
     '''
     #'$("#id_{name}").timepicker("setTime", new Date());'
     return msg.format(
         super(TimeWidget, self).render(name, value, attrs),
         name=name, initial_time=initial_time
     )
Beispiel #4
0
    def create(cls, name, groupby, realm, duration,
               resolution='auto', filterexpr=None, interface=False,
               **kwargs):
        logger.debug('Creating ProfilerTable table %s (%s) - %s/%s' %
                     (name, duration, groupby, realm))

        options = TableOptions(groupby=groupby,
                               realm=realm,
                               centricity='int' if interface else 'hos')

        t = Table(name=name, module=__name__, 
                  filterexpr=filterexpr, options=options, **kwargs)
        t.save()

        if resolution != 'auto':
            if isinstance(resolution, int):
                res = resolution
            else:
                res = int(timedelta_total_seconds(parse_timedelta(resolution)))
            resolution = rvbd.profiler.report.Report.RESOLUTION_MAP[res]

        if isinstance(duration, int):
            duration = "%d min" % duration

        fields_add_device_selection(t, keyword='profiler_device',
                                    label='Profiler', module='profiler',
                                    enabled=True)
        fields_add_time_selection(t, initial_duration=duration)
        
        fields_add_filterexpr(t)
        fields_add_resolution(t, initial=resolution,
                              resolutions=[('auto', 'Automatic'),
                                           '1min', '15min', 'hour', '6hour'],
                              special_values=['auto'])
        return t
Beispiel #5
0
    def __init__(self, **kwargs):
        self._special_values = kwargs.pop('special_values', None)
        initial = kwargs.pop('initial', None)
        if ((initial is not None) and
              (self._special_values is None or
               initial not in self._special_values)):
            initial_td = parse_timedelta(initial)
            initial_valid = False
        else:
            initial_td = None
            initial_valid = True
        choices = []

        # Rebuild the choices list to ensure that
        # the value is normalized using timedelta_str
        for choice in kwargs.pop('choices'):
            td = None
            if not (isinstance(choice, list) or isinstance(choice, tuple)):
                if (self._special_values is None or
                        choice not in self._special_values):
                    td = parse_timedelta(choice)
                    td_str = timedelta_str(td)
                    value = td_str
                    label = td_str
                else:
                    value = choice
                    label = choice

            else:
                (value, label) = choice
                if (self._special_values is None or
                        value not in self._special_values):
                    td = parse_timedelta(value)
                    value = timedelta_str(td)

            choice = (value, label)
            choices.append(choice)

            if initial_td is not None and initial_td == td:
                initial = value
                initial_valid = True

        kwargs['choices'] = choices
        if not initial_valid:
            raise KeyError('Initial duration is invalid: %s' % initial)

        super(DurationField, self).__init__(initial=initial, **kwargs)
Beispiel #6
0
    def to_python(self, value):
        if value in validators.EMPTY_VALUES:
            v = None
        elif self._special_values and value in self._special_values:
            v = value
        else:
            try:
                v = parse_timedelta(value)
            except:
                raise ValidationError('Invalid duration string: %s' % value)

        return v
Beispiel #7
0
    def decompress(self, value):
        if isinstance(value, str) or isinstance(value, unicode):
            value = timedelta_total_seconds(parse_timedelta(value))

        if value:
            m = [v for v in self.choices if v[0] == value]
            if len(m) == 1:
                return m[0]
            else:
                return [0, '%d min' % (value / 60)]

        return [None, None]
Beispiel #8
0
    def decompress(self, value):
        if isinstance(value, str) or isinstance(value, unicode):
            value = timedelta_total_seconds(parse_timedelta(value))

        if value:
            m = [v for v in self.choices if v[0] == value]
            if len(m) == 1:
                return m[0]
            else:
                return [0, '%d min' % (value / 60)]

        return [None, None]
Beispiel #9
0
    def to_python(self, value):
        if value in validators.EMPTY_VALUES:
            v = None
        elif self._special_values and value in self._special_values:
            v = value
        else:
            try:
                v = parse_timedelta(value)
            except:
                raise ValidationError('Invalid duration string: %s' % value)

        logger.debug("DurationField.to_python: %s" % v)
        return v
Beispiel #10
0
    def create(cls, name, template_id, duration,
               resolution='auto', filterexpr=None, **kwargs):
        """ Create a ProfilerTemplateTable.

        This queries a Profiler saved report template rather than creating
        a new report from scratch.

        `template_id` is a saved-report template ID
        `duration` is in minutes or a string like '15min'
        """
        logger.debug('Creating ProfilerTemplateTable table %s (%s) - %s/%s' %
                     (name, template_id, duration, resolution))

        options = TableOptions(template_id=template_id)

        t = Table(name=name, module=__name__, 
                  filterexpr=filterexpr, options=options, **kwargs)
        t.save()

        if resolution != 'auto':
            if isinstance(resolution, int):
                res = resolution
            else:
                res = int(timedelta_total_seconds(parse_timedelta(resolution)))
            resolution = rvbd.profiler.report.Report.RESOLUTION_MAP[res]

        if isinstance(duration, int):
            duration = "%d min" % duration

        fields_add_device_selection(t, keyword='profiler_device',
                                    label='Profiler', module='profiler',
                                    enabled=True)
        fields_add_time_selection(t, initial_duration=duration)
        
        fields_add_filterexpr(t)
        fields_add_resolution(t, initial=resolution,
                              resolutions=[('auto', 'Automatic'),
                                           '1min', '15min', 'hour', '6hour'],
                              special_values=['auto'])
        return t
    def run(self):
        # All user entered criteria is available directly from this object.
        # Values for any fields added to the table will appear as
        # attributes according to the field keyword.
        criteria = self.job.criteria

        # Check that a sample_device was selected
        if criteria.sample_device == "":
            logger.debug("%s: No sample device selected" % self.table)
            self.job.mark_error("No Sample Device Selected")
            return False
        sample_device = DeviceManager.get_device(criteria.sample_device)

        # Get the columns for this report
        columns = self.table.get_columns(synthetic=False)

        sortcol = None
        if self.table.sortcol is not None:
            sortcol = self.table.sortcol.name

        # Time selection is available via criterai.starttime and endtime.
        # These are both datetime objects.
        t0 = criteria.starttime
        t1 = criteria.endtime

        # Time resolution is a timedelta object
        resolution = criteria.resolution

        # Grab the custom min and max criteria
        cmin = float(criteria.min)
        cmax = float(criteria.max)

        # Grab the table options
        beta = self.table.options.beta

        # Now, do some computation -- create table with a 'time' column
        # ranging from t0 to t1 with the defined resolution.  Then
        # for each additional column do some math function on the
        # data

        t = t0
        rows = []
        while t < t1:
            row = []
            for col in columns:
                if col.name == "time":
                    row.append(t)
                else:
                    period_td = parse_timedelta(col.options.period)
                    period_secs = timedelta_total_seconds(period_td)
                    alpha = col.options.alpha
                    funcname = col.options.func

                    # seconds since the t0
                    secs = timedelta_total_seconds(t - t0)
                    rad = (secs / period_secs) * 2 * math.pi

                    funcmap = {"sin": math.sin, "cos": math.cos}

                    # Compute!
                    val = beta + alpha * funcmap[funcname](rad)

                    # Clip by the min/max criteria
                    val = max(cmin, val)
                    val = min(cmax, val)

                    # Add the value to the row
                    row.append(val)

            # Add the row
            rows.append(row)

            # This function runs pretty fast, but this shows how to mark
            # progress
            self.job.mark_progress(100 * (timedelta_total_seconds(t - t0) / timedelta_total_seconds(t1 - t0)))
            t = t + resolution

        # Save the result in self.data
        self.data = rows
        if self.table.rows > 0:
            self.data = self.data[: self.table.rows]

        logger.info("Report %s returned %s rows" % (self.job, len(self.data)))
        return True
Beispiel #12
0
    def run(self):
        # All user entered criteria is available directly from this object.
        # Values for any fields added to the table will appear as
        # attributes according to the field keyword.
        criteria = self.job.criteria

        # Check that a sample_device was selected
        if criteria.sample_device == '':
            logger.debug('%s: No sample device selected' % self.table)
            self.job.mark_error("No Sample Device Selected")
            return False
        sample_device = DeviceManager.get_device(criteria.sample_device)

        # Get the columns for this report
        columns = self.table.get_columns(synthetic=False)

        sortcol = None
        if self.table.sortcol is not None:
            sortcol = self.table.sortcol.name

        # Time selection is available via criterai.starttime and endtime.
        # These are both datetime objects.
        t0 = criteria.starttime
        t1 = criteria.endtime

        # Time resolution is a timedelta object
        resolution = criteria.resolution

        # Grab the custom min and max criteria
        cmin = float(criteria.min)
        cmax = float(criteria.max)

        # Grab the table options
        beta = self.table.options.beta

        # Now, do some computation -- create table with a 'time' column
        # ranging from t0 to t1 with the defined resolution.  Then
        # for each additional column do some math function on the
        # data

        t = t0
        rows = []
        while t < t1:
            row = []
            for col in columns:
                if col.name == 'time':
                    row.append(t)
                else:
                    period_td = parse_timedelta(col.options.period)
                    period_secs = timedelta_total_seconds(period_td)
                    alpha = col.options.alpha
                    funcname = col.options.func

                    # seconds since the t0
                    secs = timedelta_total_seconds(t - t0)
                    rad = (secs / period_secs) * 2 * math.pi

                    funcmap = {
                        'sin': math.sin,
                        'cos': math.cos,
                    }

                    # Compute!
                    val = beta + alpha * funcmap[funcname](rad)

                    # Clip by the min/max criteria
                    val = max(cmin, val)
                    val = min(cmax, val)

                    # Add the value to the row
                    row.append(val)

            # Add the row
            rows.append(row)

            # This function runs pretty fast, but this shows how to mark
            # progress
            self.job.mark_progress(100 * (timedelta_total_seconds(t - t0) /
                                          timedelta_total_seconds(t1 - t0)))
            t = t + resolution

        # Save the result in self.data
        self.data = rows
        if self.table.rows > 0:
            self.data = self.data[:self.table.rows]

        logger.info("Report %s returned %s rows" % (self.job, len(self.data)))
        return True
Beispiel #13
0
class TableQuery:
    # Used by Table to actually run a query
    def __init__(self, table, job):
        self.table = table
        self.job = job
        self.timeseries = False  # if key column called 'time' is created
        self.column_names = []

        # Resolution comes in as a time_delta
        resolution = timedelta_total_seconds(job.criteria.resolution)

        default_delta = 1000000000  # one second
        self.delta = int(default_delta * resolution)  # sample size interval

    def fake_run(self):
        import fake_data
        self.data = fake_data.make_data(self.table, self.job)

    def run(self):
        """ Main execution method
        """
        criteria = self.job.criteria

        if criteria.shark_device == '':
            logger.debug('%s: No shark device selected' % self.table)
            self.job.mark_error("No Shark Device Selected")
            return False

        #self.fake_run()
        #return True

        shark = DeviceManager.get_device(criteria.shark_device)

        logger.debug("Creating columns for Shark table %d" % self.table.id)

        # Create Key/Value Columns
        columns = []
        for tc in self.table.get_columns(synthetic=False):
            tc_options = tc.options
            if (tc.iskey and tc.name == 'time'
                    and tc_options.extractor == 'sample_time'):
                # don't create column, use the sample time for timeseries
                self.timeseries = True
                self.column_names.append('time')
                continue
            elif tc.iskey:
                c = Key(tc_options.extractor,
                        description=tc.label,
                        default_value=tc_options.default_value)
            else:
                if tc_options.operation:
                    try:
                        operation = getattr(Operation, tc_options.operation)
                    except AttributeError:
                        operation = Operation.sum
                        print('ERROR: Unknown operation attribute '
                              '%s for column %s.' %
                              (tc_options.operation, tc.name))
                else:
                    operation = Operation.none

                c = Value(tc_options.extractor,
                          operation,
                          description=tc.label,
                          default_value=tc_options.default_value)
                self.column_names.append(tc.name)

            columns.append(c)

        # Identify Sort Column
        sortidx = None
        if self.table.sortcol is not None:
            sort_name = self.table.sortcol.options.extractor
            for i, c in enumerate(columns):
                if c.field == sort_name:
                    sortidx = i
                    break

        # Initialize filters
        criteria = self.job.criteria

        filters = []
        filterexpr = self.job.combine_filterexprs(
            exprs=criteria.shark_filterexpr, joinstr="&")
        if filterexpr:
            filters.append(SharkFilter(filterexpr))

        tf = TimeFilter(start=criteria.starttime, end=criteria.endtime)
        filters.append(tf)

        logger.info("Setting shark table %d timeframe to %s" %
                    (self.table.id, str(tf)))

        # Get source type from options
        try:
            with lock:
                source = path_to_class(shark,
                                       self.job.criteria.shark_source_name)

        except RvbdHTTPException, e:
            source = None
            raise e

        resolution = criteria.resolution
        if resolution.seconds == 1:
            sampling_time_msec = 1000
        elif resolution.microseconds == 1000:
            sampling_time_msec = 1
            if criteria.duration > parse_timedelta('1s'):
                msg = ("Cannot run a millisecond report with a duration "
                       "longer than 1 second")
                raise ValueError(msg)
        else:
            sampling_time_msec = 1000

        # Setup the view
        if source is not None:
            with lock:
                view = shark.create_view(source,
                                         columns,
                                         filters=filters,
                                         sync=False,
                                         sampling_time_msec=sampling_time_msec)
        else:
            # XXX raise other exception
            return None

        done = False
        logger.debug("Waiting for shark table %d to complete" % self.table.id)
        while not done:
            time.sleep(0.5)
            with lock:
                s = view.get_progress()
                self.job.progress = s
                self.job.save()
            done = (s == 100)

        # Retrieve the data
        with lock:
            if self.table.options.aggregated:
                self.data = view.get_data(
                    aggregated=self.table.options.aggregated, sortby=sortidx)
            else:
                self.data = view.get_data(delta=self.delta, sortby=sortidx)
            view.close()

        if self.table.rows > 0:
            self.data = self.data[:self.table.rows]

        self.parse_data()

        logger.info("Shark Report %s returned %s rows" %
                    (self.job, len(self.data)))

        return True
Beispiel #14
0
    def run(
        self, template_id, timefilter=None, resolution="auto", query=None, trafficexpr=None, data_filter=None, sync=True
    ):
        """Create the report on Profiler and begin running
        the report.  If the `sync` option is True, periodically
        poll until the report is complete, otherwise return
        immediately.

        `template_id` is the numeric id of the template to use for the report

        `timefilter` is the range of time to query, a TimeFilter object
        
        `resolution` is the data resolution (1min, 15min, etc.), defaults to 'auto'

        `query` is the query object containing criteria

        `trafficexpr` is a TrafficFilter object

        `data_filter` is a deprecated filter to run against report data

        `sync` if True, poll for status until the report is complete
        """

        self.template_id = template_id
        self.custom_columns = False
        if self.template_id != 184:
            # the columns in this report won't match, use custom columns instead
            self.custom_columns = True

        if timefilter is None:
            self.timefilter = TimeFilter.parse_range("last 5 min")
        else:
            self.timefilter = timefilter
        self.query = query
        self.trafficexpr = trafficexpr

        self.data_filter = data_filter

        self.id = None
        self.queries = list()
        self.last_status = None

        if resolution not in ["auto", "1min", "15min", "hour", "6hour", "day", "week", "month"]:
            rd = parse_timedelta(resolution)
            resolution = self.RESOLUTION_MAP[int(timedelta_total_seconds(rd))]

        self.resolution = resolution

        start = datetime_to_seconds(self.timefilter.start)
        end = datetime_to_seconds(self.timefilter.end)

        # using a RecursiveUpdateDict
        criteria = RecursiveUpdateDict(**{"time_frame": {"start": int(start), "end": int(end)}})

        if self.query is not None:
            criteria["query"] = self.query

        if self.resolution != "auto":
            criteria["time_frame"]["resolution"] = self.resolution

        if self.data_filter:
            criteria["deprecated"] = {self.data_filter[0]: self.data_filter[1]}

        if self.trafficexpr is not None:
            criteria["traffic_expression"] = self.trafficexpr.filter

        to_post = {"template_id": self.template_id, "criteria": criteria}

        logger.debug("Posting JSON: %s" % to_post)

        response = self.profiler.api.report.reports(data=to_post)

        try:
            self.id = int(response["id"])
        except KeyError:
            raise ValueError("failed to retrieve report id from report creation response: %s" % response)

        logger.info("Created report %d" % self.id)

        if sync:
            self.wait_for_complete()