def test_custom(self):
        transform = TimestampTransform(time_format=timestamp.DATE_FORMAT)

        self.assertIsNone(transform.transform(None))

        result = transform.transform('blah')
        today = timestamp.date_str()
        self.assertEqual(result.split()[0], today)
        self.assertEqual(result.split()[1], 'blah')
    def test_default(self):
        transform = TimestampTransform()

        self.assertIsNone(transform.transform(None))

        result = transform.transform('blah')
        time_str = result.split()[0]
        then = timestamp.timestamp(time_str=time_str)
        now = timestamp.timestamp()

        self.assertAlmostEqual(then, now, places=1)
        self.assertEqual(result.split()[1], 'blah')
    def test_list(self):
        transform = TimestampTransform()

        self.assertIsNone(transform.transform(None))

        record = ['foo', 'bar', 'baz']
        result = transform.transform(record)
        timestamps = [r.split()[0] for r in result]
        self.assertEqual(timestamps[0], timestamps[1])
        self.assertEqual(timestamps[1], timestamps[2])

        then = timestamp.timestamp(time_str=timestamps[0])
        now = timestamp.timestamp()
        self.assertAlmostEqual(then, now, places=1)

        sources = [r.split()[1] for r in result]
        self.assertEqual(sources, record)
예제 #4
0
class SimNetwork:
    """Open a network port and feed stored logfile data to it."""

    ############################

    def __init__(self, port, filebase, instrument):
        """
        ```
        port -  UDP port on which to write records.

        filebase - Prefix string to be matched (with a following "*") to fine
                   files to be used. e.g. /tmp/log/NBP1406/knud/raw/NBP1406_knud

        instrument - Instrument name prefix to add before sendind out on wire
        ```
        """
        self.filebase = filebase
        self.reader = LogfileReader(filebase=filebase, use_timestamps=True)
        self.slice_n = SliceTransform(
            fields='1:')  # grab 2nd and subsequent fields
        self.timestamp = TimestampTransform()
        self.prefix = PrefixTransform(instrument)
        self.writer = UDPWriter(port=port)
        self.instrument = instrument
        self.first_time = True
        self.quit_flag = False

    ############################
    def run(self, loop=False):
        """Start reading and writing data. If loop==True, loop when reaching
        end of input.
        """
        logging.info('Starting %s', self.instrument)
        try:
            while not self.quit_flag:
                record = self.reader.read()

                # If we don't have a record, we're (probably) at the end of
                # the file. If it's the first time we've tried reading, it
                # means we probably didn't get a usable file. Either break out
                # (if we're not looping, or if we don't have a usable file),
                # or start reading from the beginning (if we are looping and
                # have a usable file).
                if not record:
                    if not loop or self.first_time:
                        break
                    logging.info('Looping instrument %s', self.instrument)
                    self.reader = LogfileReader(filebase=self.filebase,
                                                use_timestamps=True)
                    continue

                # Strip off timestamp and tack on a new one
                record = self.slice_n.transform(record)
                record = self.timestamp.transform(record)

                # Add instrument name back on, and write to specified network
                record = self.prefix.transform(record)
                self.writer.write(record)
                self.first_time = False

        except (OSError, KeyboardInterrupt):
            self.quit_flag = True

        logging.info('Finished %s', self.instrument)
예제 #5
0
class SimSerial:
  """Create a virtual serial port and feed stored logfile data to it."""
  ############################
  def __init__(self, port, prefix=None, timestamp=False,
               time_format=TIME_FORMAT, filebase=None, eol='\n',
               baudrate=9600, bytesize=8, parity='N', stopbits=1,
               timeout=None, xonxoff=False, rtscts=False, write_timeout=None,
               dsrdtr=False, inter_byte_timeout=None, exclusive=None):
    """
    Simulate a serial port, feeding it data from the specified file.

    ```
    port - Temporary serial port to create and make available for reading
           records.

    prefix - If non-empty, prefix name prefix to add

    timestamp = If True, apply current timestamp to record

    time_format - What format to use for timestamp
    ```
    """
    # We'll create two virtual ports: 'port' and 'port_in'; we will write
    # to port_in and read the values back out from port
    self.read_port = port
    self.write_port = port + '_in'
    self.prefix = PrefixTransform(prefix) if prefix else None
    self.timestamp = TimestampTransform() if timestamp else None
    self.time_format = time_format
    self.filebase = filebase
    self.serial_params = None

    # Complain, but go ahead if read_port or write_port exist.
    for path in [self.read_port, self.write_port]:
      if os.path.exists(path):
        logging.warning('Path %s exists; overwriting!')

    # Do we have any files we can actually read from?
    if not glob.glob(filebase + '*'):
      logging.warning('%s: no files matching "%s*"', prefix, filebase)
      return

    # Set up our parameters
    self.serial_params = {'baudrate': baudrate,
                          'byteside': bytesize,
                          'parity': parity,
                          'stopbits': stopbits,
                          'timeout': timeout,
                          'xonxoff': xonxoff,
                          'rtscts': rtscts,
                          'write_timeout': write_timeout,
                          'dsrdtr': dsrdtr,
                          'inter_byte_timeout': inter_byte_timeout,
                          'exclusive': exclusive}
    self.quit = False

    # Finally, find path to socat executable
    self.socat_path = None
    for socat_path in ['/usr/bin/socat', '/usr/local/bin/socat']:
      if os.path.exists(socat_path) and os.path.isfile(socat_path):
        self.socat_path = socat_path
    if not self.socat_path:
      raise NameError('Executable "socat" not found on path. Please refer '
                      'to installation guide to install socat.')

  ############################
  def _run_socat(self):
    """Internal: run the actual command."""
    verbose = '-d'
    write_port_params =   'pty,link=%s,raw,echo=0' % self.write_port
    read_port_params = 'pty,link=%s,raw,echo=0' % self.read_port

    cmd = [self.socat_path,
           verbose,
           #verbose,   # repeating makes it more verbose
           read_port_params,
           write_port_params,
          ]
    try:
      # Run socat process using Popen, checking every second or so whether
      # it's died (poll() != None) or we've gotten a quit signal.
      logging.info('Calling: %s', ' '.join(cmd))
      socat_process = subprocess.Popen(cmd)
      while not self.quit and not socat_process.poll():
        try:
          socat_process.wait(1)
        except subprocess.TimeoutExpired:
          pass

    except Exception as e:
      logging.error('ERROR: socat command: %s', e)

    # If here, process has terminated, or we've seen self.quit. We
    # want both to be true: if we've terminated, set self.quit so that
    # 'run' loop can exit. If self.quit, terminate process.
    if self.quit:
      socat_process.kill()
    else:
      self.quit = True
    logging.info('Finished: %s', ' '.join(cmd))

  ############################
  def run(self, loop=False):
    # If self.serial_params is None, it means that either read or
    # write device already exist, so we shouldn't actually run, or
    # we'll destroy them.
    if not self.serial_params:
      return

    """Create the virtual port with socat and start feeding it records from
    the designated logfile. If loop==True, loop when reaching end of input."""
    self.socat_thread = threading.Thread(target=self._run_socat, daemon=True)
    self.socat_thread.start()
    time.sleep(0.2)

    self.reader = LogfileReader(filebase=self.filebase, use_timestamps=True,
                                time_format=self.time_format)

    self.slice_n = SliceTransform('1:') # strip off the first field (timestamp)
    self.writer = TextFileWriter(self.write_port, truncate=True)

    logging.info('Starting %s: %s', self.read_port, self.filebase)
    while not self.quit:
      try:
        record = self.reader.read() # get the next record
        logging.debug('SimSerial got: %s', record)

        # End of input? If loop==True, re-open the logfile from the start
        if record is None:
          if not loop:
            break
          self.reader = LogfileReader(filebase=self.filebase,
                                      use_timestamps=True,
                                      time_format=self.time_format)

        record = self.slice_n.transform(record)  # strip the timestamp
        if not record:
          continue
        if self.timestamp:      # do we want to add a timestamp?
          record = self.timestamp.transform(record)
        if self.prefix:         # do we want to add prefix?
          record = self.prefix.transform(record)

        logging.debug('SimSerial writing: %s', record)
        self.writer.write(record)   # and write it to the virtual port
      except (OSError, KeyboardInterrupt):
        break

    # If we're here, we got None from our input, and are done. Signal
    # for run_socat to exit
    self.quit = True
예제 #6
0
class SimUDP:
  """Open a network port and feed stored logfile data to it."""
  ############################
  def __init__(self, port, prefix=None, timestamp=False,
               time_format=TIME_FORMAT, filebase=None, eol='\n'):
    """
    ```
    port -  UDP port on which to write records.

    prefix - If non-empty, prefix to add

    timestamp = If True, apply current timestamp to record

    time_format - What format to use for timestamp

    filebase - Prefix string to be matched (with a following "*") to find
               files to be used. e.g. /tmp/log/NBP1406/knud/raw/NBP1406_knud
    ```
    """
    self.port = port
    self.prefix = PrefixTransform(prefix) if prefix else None
    self.timestamp = TimestampTransform() if timestamp else None
    self.time_format = time_format
    self.filebase = filebase

    # Do we have any files we can actually read from?
    if not glob.glob(filebase + '*'):
      logging.warning('No files matching "%s*"', filebase)
      self.quit_flag = True
      return

    self.reader = LogfileReader(filebase=filebase, use_timestamps=True,
                                time_format=self.time_format)
    self.slice_n = SliceTransform(fields='1:') # strip off timestamp
    self.writer = UDPWriter(port=port, eol=eol)

    self.first_time = True
    self.quit_flag = False

  ############################
  def run(self, loop=False):
    """Start reading and writing data. If loop==True, loop when reaching
    end of input.
    """
    logging.info('Starting %s: %s', self.port, self.filebase)
    try:
      while not self.quit_flag:
        record = self.reader.read()

        # If we don't have a record, we're (probably) at the end of
        # the file. If it's the first time we've tried reading, it
        # means we probably didn't get a usable file. Either break out
        # (if we're not looping, or if we don't have a usable file),
        # or start reading from the beginning (if we are looping and
        # have a usable file).
        if not record:
          if not loop or self.first_time:
            break
          logging.info('Looping instrument %s', self.prefix)
          self.reader = LogfileReader(filebase=self.filebase,
                                      use_timestamps=True)
          continue

        # Strip off timestamp
        record =  self.slice_n.transform(record)
        if not record:
          continue
        record = record.strip()
        if not record:
          continue

        if self.timestamp:      # do we want to add a timestamp?
          record = self.timestamp.transform(record)
        if self.prefix:         # do we want to add prefix?
          record = self.prefix.transform(record)

        self.writer.write(record)
        self.first_time = False

    except (OSError, KeyboardInterrupt):
      self.quit_flag = True

    logging.info('Finished %s', self.prefix)
예제 #7
0
    reader = TextFileReader(file_spec=args.read, tail=args.tail)
    writer = TextFileWriter(filename=args.write)

    if args.prefix:
        prefix_transform = PrefixTransform(args.prefix)

    if args.timestamp:
        timestamp_transform = TimestampTransform()

    while True:
        record = reader.read()
        now = time.time()

        logging.info('Got record: %s', record)

        if record is None:
            if not args.tail:
                break
        else:
            if args.timestamp:
                record = timestamp_transform.transform(record)

            if args.prefix:
                record = prefix_transform.transform(record)

            writer.write(record)

        if args.interval:
            time_to_sleep = max(0, args.interval - (time.time() - now))
            time.sleep(time_to_sleep)