예제 #1
0
    def queue_it(self, count):
        try:
            realtime = self.sample.now(realnow=True)
            if "-" in self.sample.backfill[0]:
                mathsymbol = "-"
            else:
                mathsymbol = "+"
            backfillnumber = ""
            backfillletter = ""
            for char in self.sample.backfill:
                if char.isdigit():
                    backfillnumber += char
                elif char != "-":
                    backfillletter += char
            backfillearliest = timeParserTimeMath(
                plusminus=mathsymbol,
                num=backfillnumber,
                unit=backfillletter,
                ret=realtime,
            )
            while backfillearliest < realtime:
                et = backfillearliest
                lt = timeParserTimeMath(plusminus="+",
                                        num=self.sample.interval,
                                        unit="s",
                                        ret=et)
                genPlugin = self.generatorPlugin(sample=self.sample)
                genPlugin.updateCounts(count=count, start_time=et, end_time=lt)
                genPlugin.updateConfig(config=self.config,
                                       outqueue=self.outputQueue)
                try:
                    # Need to lock on replay mode since event duration is dynamic.  Interval starts counting
                    # after the replay has finished.
                    if self.sample.generator == "replay":
                        genPlugin.run()
                    else:
                        self.generatorQueue.put(genPlugin)
                except Full:
                    logger.warning(
                        "Generator Queue Full. Skipping current generation.")
                # due to replays needing to iterate in reverse, it's more efficent to process backfill
                # after the file has been parsed.  This section is to allow replay mode to take
                # care of all replays on it's first run. and sets backfilldone
                if self.sample.generator == "replay":
                    backfillearliest = realtime
                else:
                    backfillearliest = lt
            if self.sample.generator != "replay":
                self.sample.backfilldone = True

        except Exception as e:
            logger.error("Failed queuing backfill, exception: {0}".format(e))
예제 #2
0
def test_time_parser_time_math(plusminus, num, unit, ret, expect):
    '''
    test timeParserTimeMath function, parse the time modifier
    Normal Case:
    Case 1: input "+100s" -- the parser should translate it as 100 seconds later.
    Case 2: input "-20m" -- the parser should handle the month larger than 12 and translate as 20 months ago
    Case 3: input '3w' -- the parser should translate as 21 days later.

    Corner Cases:
    Case 1: input "0s" -- the time parser should return now
    Case 2: input "123" -- unit is the empty string, behavior <TBD>
    '''
    check_datetime_equal(timeparser.timeParserTimeMath(plusminus, num, unichr, ret), expect)
예제 #3
0
def test_time_parser_time_math(plusminus, num, unit, ret, expect):
    '''
    test timeParserTimeMath function, parse the time modifier
    Normal Case:
    Case 1: input "+100s" -- the parser should translate it as 100 seconds later.
    Case 2: input "-20m" -- the parser should handle the month larger than 12 and translate as 20 months ago
    Case 3: input '3w' -- the parser should translate as 21 days later.

    Corner Cases:
    Case 1: input "0s" -- the time parser should return now
    Case 2: input "123" -- unit is the empty string, behavior <TBD>
    '''
    check_datetime_equal(
        timeparser.timeParserTimeMath(plusminus, num, chr, ret), expect)
예제 #4
0
    def real_run(self):
        """
        Worker function of the Timer class.  Determine whether a plugin is queueable, and either
        place an item in the generator queue for that plugin or call the plugin's gen method directly.
        """
        if self.sample.delay > 0:
            logger.info("Sample set to delay %s, sleeping." %
                        self.sample.delay)
            time.sleep(self.sample.delay)

        logger.debug("Timer creating plugin for '%s'" % self.sample.name)

        end = False
        previous_count_left = 0
        raw_event_size = self.predict_event_size()
        if self.end:
            if int(self.end) == 0:
                logger.info(
                    "End = 0, no events will be generated for sample '%s'" %
                    self.sample.name)
                end = True
            elif int(self.end) == -1:
                logger.info(
                    "End is set to -1. Will be running without stopping for sample %s"
                    % self.sample.name)
        while not end:
            # Need to be able to stop threads by the main thread or this thread. self.config will stop all threads
            # referenced in the config object, while, self.stopping will only stop this one.
            if self.config.stopping or self.stopping:
                end = True
                continue
            count = self.rater.rate()
            # First run of the generator, see if we have any backfill work to do.
            if self.countdown <= 0:
                if self.sample.backfill and not self.sample.backfilldone:
                    realtime = self.sample.now(realnow=True)
                    if "-" in self.sample.backfill[0]:
                        mathsymbol = "-"
                    else:
                        mathsymbol = "+"
                    backfillnumber = ""
                    backfillletter = ""
                    for char in self.sample.backfill:
                        if char.isdigit():
                            backfillnumber += char
                        elif char != "-":
                            backfillletter += char
                    backfillearliest = timeParserTimeMath(plusminus=mathsymbol,
                                                          num=backfillnumber,
                                                          unit=backfillletter,
                                                          ret=realtime)
                    while backfillearliest < realtime:
                        if self.end and self.executions == int(self.end):
                            logger.info(
                                "End executions %d reached, ending generation of sample '%s'"
                                % (int(self.end), self.sample.name))
                            break
                        et = backfillearliest
                        lt = timeParserTimeMath(plusminus="+",
                                                num=self.interval,
                                                unit="s",
                                                ret=et)
                        copy_sample = copy.copy(self.sample)
                        tokens = copy.deepcopy(self.sample.tokens)
                        copy_sample.tokens = tokens
                        genPlugin = self.generatorPlugin(sample=copy_sample)
                        # need to make sure we set the queue right if we're using multiprocessing or thread modes
                        genPlugin.updateConfig(config=self.config,
                                               outqueue=self.outputQueue)
                        genPlugin.updateCounts(count=count,
                                               start_time=et,
                                               end_time=lt)
                        try:
                            self.generatorQueue.put(genPlugin, True, 3)
                            self.executions += 1
                            backfillearliest = lt
                        except Full:
                            logger.warning(
                                "Generator Queue Full. Reput the backfill generator task later. %d backfill generators are dispatched.",
                                self.executions)
                            backfillearliest = et
                        realtime = self.sample.now(realnow=True)

                    self.sample.backfilldone = True
                else:
                    # 12/15/13 CS Moving the rating to a separate plugin architecture
                    # Save previous interval count left to avoid perdayvolumegenerator drop small tasks
                    if self.sample.generator == 'perdayvolumegenerator':
                        count = self.rater.rate() + previous_count_left
                        if 0 < count < raw_event_size:
                            logger.info(
                                "current interval size is {}, which is smaller than a raw event size {}."
                                .format(count, raw_event_size) +
                                "Wait for the next turn.")
                            previous_count_left = count
                            self.countdown = self.interval
                            self.executions += 1
                            continue
                        else:
                            previous_count_left = 0
                    else:
                        count = self.rater.rate()

                    et = self.sample.earliestTime()
                    lt = self.sample.latestTime()

                    try:
                        if count < 1 and count != -1:
                            logger.info(
                                "There is no data to be generated in worker {0} because the count is {1}."
                                .format(self.sample.config.generatorWorkers,
                                        count))
                        else:
                            # Spawn workers at the beginning of job rather than wait for next interval
                            logger.info(
                                "Starting '%d' generatorWorkers for sample '%s'"
                                % (self.sample.config.generatorWorkers,
                                   self.sample.name))
                            for worker_id in range(
                                    self.config.generatorWorkers):
                                copy_sample = copy.copy(self.sample)
                                tokens = copy.deepcopy(self.sample.tokens)
                                copy_sample.tokens = tokens
                                genPlugin = self.generatorPlugin(
                                    sample=copy_sample)
                                # Adjust queue for threading mode
                                genPlugin.updateConfig(
                                    config=self.config,
                                    outqueue=self.outputQueue)
                                genPlugin.updateCounts(count=count,
                                                       start_time=et,
                                                       end_time=lt)

                                try:
                                    self.generatorQueue.put(genPlugin)
                                    logger.debug((
                                        "Worker# {0}: Put {1} MB of events in queue for sample '{2}'"
                                        + "with et '{3}' and lt '{4}'").format(
                                            worker_id,
                                            round((count / 1024.0 / 1024), 4),
                                            self.sample.name, et, lt))
                                except Full:
                                    logger.warning(
                                        "Generator Queue Full. Skipping current generation."
                                    )
                            self.executions += 1
                    except Exception as e:
                        logger.exception(str(e))
                        if self.stopping:
                            end = True
                        pass

                # Sleep until we're supposed to wake up and generate more events
                self.countdown = self.interval

                # 8/20/15 CS Adding support for ending generation at a certain time

                if self.end:
                    if int(self.end) == -1:
                        time.sleep(self.time)
                        self.countdown -= self.time
                        continue
                    # 3/16/16 CS Adding support for ending on a number of executions instead of time
                    # Should be fine with storing state in this sample object since each sample has it's own unique
                    # timer thread
                    if not self.endts:
                        if self.executions >= int(self.end):
                            logger.info(
                                "End executions %d reached, ending generation of sample '%s'"
                                % (int(self.end), self.sample.name))
                            self.stopping = True
                            end = True
                    elif lt >= self.endts:
                        logger.info(
                            "End Time '%s' reached, ending generation of sample '%s'"
                            % (self.sample.endts, self.sample.name))
                        self.stopping = True
                        end = True

            else:
                time.sleep(self.time)
                self.countdown -= self.time