docs: def logs(stage, period, tail, config_file):
      """Dump logs to the console."""
      config = _load_config(config_file)
      if stage is None:
          stage = config['devstage']
  
      cfn = boto3.client('cloudformation')
      try:
          stack = cfn.describe_stacks(StackName=config['name'])['Stacks'][0]
      except botocore.exceptions.ClientError:
          print('{} has not been deployed yet.'.format(config['name']))
          return
      function = _get_from_stack(stack, 'Output', 'FunctionArn').split(':')[-1]
      version = _get_from_stack(stack, 'Parameter', stage.title() + 'Version')
      api_id = _get_from_stack(stack, 'Output', 'ApiId')
  
      try:
          start = float(period[:-1])
      except ValueError:
          raise ValueError('Invalid period ' + period)
      if period[-1] == 's':
          start = time.time() - start
      elif period[-1] == 'm':
          start = time.time() - start * 60
      elif period[-1] == 'h':
          start = time.time() - start * 60 * 60
      elif period[-1] == 'd':
          start = time.time() - start * 60 * 60 * 24
      elif period[-1] == 'w':
          start = time.time() - start * 60 * 60 * 24 * 7
      else:
          raise ValueError('Invalid period ' + period)
      start = int(start * 1000)
  
      logs = boto3.client('logs')
      lambda_log_group = '/aws/lambda/' + function
      log_groups = [lambda_log_group]
      if api_id:
          log_groups.append('API-Gateway-Execution-Logs_' + api_id + '/' + stage)
      log_version = '[' + version + ']'
      log_start = {g: start for g in log_groups}
      while True:
          kwargs = {}
          events = []
          for log_group in log_groups:
              while True:
                  try:
                      l = logs.filter_log_events(logGroupName=log_group,
                                                 startTime=log_start[log_group],
                                                 interleaved=True, **kwargs)
                  except botocore.exceptions.ClientError:
                      # the log group does not exist yet
                      l = {'events': []}
                  if log_group == lambda_log_group:
                      events += [ev for ev in l['events']
                                 if log_version in ev['logStreamName']]
                  else:
                      events += l['events']
                  if len(l['events']):
                      log_start[log_group] = l['events'][-1]['timestamp'] + 1
                  if 'nextToken' not in l:
                      break
                  kwargs['nextToken'] = l['nextToken']
          events.sort(key=lambda ev: ev['timestamp'])
          for ev in events:
              tm = datetime.fromtimestamp(ev['timestamp'] / 1000)
              print(tm.strftime('%b %d %X ') + ev['message'].strip())
          if not tail:
              break
          time.sleep(5)