예제 #1
0
def log_handler(end_event):
  if PC:
    return

  log_files = []
  last_scan = 0
  while not end_event.is_set():
    try:
      curr_scan = sec_since_boot()
      if curr_scan - last_scan > 10:
        log_files = get_logs_to_send_sorted()
        last_scan = curr_scan

      # send one log
      curr_log = None
      if len(log_files) > 0:
        log_entry = log_files.pop() # newest log file
        cloudlog.debug(f"athena.log_handler.forward_request {log_entry}")
        try:
          curr_time = int(time.time())
          log_path = os.path.join(SWAGLOG_DIR, log_entry)
          setxattr(log_path, LOG_ATTR_NAME, int.to_bytes(curr_time, 4, sys.byteorder))
          with open(log_path, "r") as f:
            jsonrpc = {
              "method": "forwardLogs",
              "params": {
                "logs": f.read()
              },
              "jsonrpc": "2.0",
              "id": log_entry
            }
            log_send_queue.put_nowait(json.dumps(jsonrpc))
            curr_log = log_entry
        except OSError:
          pass  # file could be deleted by log rotation

      # wait for response up to ~100 seconds
      # always read queue at least once to process any old responses that arrive
      for _ in range(100):
        if end_event.is_set():
          break
        try:
          log_resp = json.loads(log_recv_queue.get(timeout=1))
          log_entry = log_resp.get("id")
          log_success = "result" in log_resp and log_resp["result"].get("success")
          cloudlog.debug(f"athena.log_handler.forward_response {log_entry} {log_success}")
          if log_entry and log_success:
            log_path = os.path.join(SWAGLOG_DIR, log_entry)
            try:
              setxattr(log_path, LOG_ATTR_NAME, LOG_ATTR_VALUE_MAX_UNIX_TIME)
            except OSError:
              pass  # file could be deleted by log rotation
          if curr_log == log_entry:
            break
        except queue.Empty:
          if curr_log is None:
            break

    except Exception:
      cloudlog.exception("athena.log_handler.exception")
예제 #2
0
  def upload(self, key, fn):
    try:
      sz = os.path.getsize(fn)
    except OSError:
      cloudlog.exception("upload: getsize failed")
      return False

    cloudlog.event("upload", key=key, fn=fn, sz=sz)

    cloudlog.info("checking %r with size %r", key, sz)

    if sz == 0:
      try:
        # tag files of 0 size as uploaded
        setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
      except OSError:
        cloudlog.event("uploader_setxattr_failed", exc=self.last_exc, key=key, fn=fn, sz=sz)
      success = True
    else:
      cloudlog.info("uploading %r", fn)
      stat = self.normal_upload(key, fn)
      if stat is not None and stat.status_code in (200, 201, 412):
        cloudlog.event("upload_success" if stat.status_code != 412 else "upload_ignored", key=key, fn=fn, sz=sz)
        try:
          # tag file as uploaded
          setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
        except OSError:
          cloudlog.event("uploader_setxattr_failed", exc=self.last_exc, key=key, fn=fn, sz=sz)
        success = True
      else:
        cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz)
        success = False

    return success
예제 #3
0
    def upload(self, name, key, fn, network_type, metered):
        try:
            sz = os.path.getsize(fn)
        except OSError:
            cloudlog.exception("upload: getsize failed")
            return False

        cloudlog.event("upload_start",
                       key=key,
                       fn=fn,
                       sz=sz,
                       network_type=network_type,
                       metered=metered)

        if sz == 0:
            # tag files of 0 size as uploaded
            success = True
        elif name in self.immediate_priority and sz > UPLOAD_QLOG_QCAM_MAX_SIZE:
            cloudlog.event("uploader_too_large", key=key, fn=fn, sz=sz)
            success = True
        else:
            start_time = time.monotonic()
            stat = self.normal_upload(key, fn)
            if stat is not None and stat.status_code in (200, 201, 401, 403,
                                                         412):
                self.last_filename = fn
                self.last_time = time.monotonic() - start_time
                self.last_speed = (sz / 1e6) / self.last_time
                success = True
                cloudlog.event("upload_success" if stat.status_code != 412 else
                               "upload_ignored",
                               key=key,
                               fn=fn,
                               sz=sz,
                               network_type=network_type,
                               metered=metered)
            else:
                success = False
                cloudlog.event("upload_failed",
                               stat=stat,
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz,
                               network_type=network_type,
                               metered=metered)

        if success:
            # tag file as uploaded
            try:
                setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
            except OSError:
                cloudlog.event("uploader_setxattr_failed",
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz)

        return success
예제 #4
0
    def upload(self, key, fn, network_type):
        try:
            sz = os.path.getsize(fn)
        except OSError:
            cloudlog.exception("upload: getsize failed")
            return False

        cloudlog.event("upload_start",
                       key=key,
                       fn=fn,
                       sz=sz,
                       network_type=network_type)

        if sz == 0:
            try:
                # tag files of 0 size as uploaded
                setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
            except OSError:
                cloudlog.event("uploader_setxattr_failed",
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz)
            success = True
        else:
            start_time = time.monotonic()
            stat = self.normal_upload(key, fn)
            if stat is not None and stat.status_code in (200, 201, 403, 412):
                try:
                    # tag file as uploaded
                    setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
                except OSError:
                    cloudlog.event("uploader_setxattr_failed",
                                   exc=self.last_exc,
                                   key=key,
                                   fn=fn,
                                   sz=sz)

                self.last_filename = fn
                self.last_time = time.monotonic() - start_time
                self.last_speed = (sz / 1e6) / self.last_time
                success = True
                cloudlog.event("upload_success" if stat.status_code != 412 else
                               "upload_ignored",
                               key=key,
                               fn=fn,
                               sz=sz,
                               network_type=network_type)
            else:
                success = False
                cloudlog.event("upload_failed",
                               stat=stat,
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz,
                               network_type=network_type)

        return success
예제 #5
0
def log_handler(end_event):
    if PC:
        return

    log_files = []
    last_scan = 0
    log_retries = 0
    while not end_event.is_set():
        try:
            try:
                result = json.loads(log_recv_queue.get(timeout=1))
                log_success = result.get("success")
                log_entry = result.get("id")
                log_path = os.path.join(SWAGLOG_DIR, log_entry)
                if log_entry and log_success:
                    try:
                        setxattr(log_path, LOG_ATTR_NAME,
                                 LOG_ATTR_VALUE_MAX_UNIX_TIME)
                    except OSError:
                        pass  # file could be deleted by log rotation
            except queue.Empty:
                pass

            curr_scan = sec_since_boot()
            if curr_scan - last_scan > 10:
                log_files = get_logs_to_send_sorted()
                last_scan = curr_scan

            # never send last log file because it is the active log
            # and only send one log file at a time (most recent first)
            if not len(log_files) or not log_send_queue.empty():
                continue

            log_entry = log_files.pop()
            try:
                curr_time = int(time.time())
                log_path = os.path.join(SWAGLOG_DIR, log_entry)
                setxattr(log_path, LOG_ATTR_NAME,
                         int.to_bytes(curr_time, 4, sys.byteorder))
                with open(log_path, "r") as f:
                    jsonrpc = {
                        "method": "forwardLogs",
                        "params": {
                            "logs": f.read()
                        },
                        "jsonrpc": "2.0",
                        "id": log_entry
                    }
                    log_send_queue.put_nowait(json.dumps(jsonrpc))
            except OSError:
                pass  # file could be deleted by log rotation
            log_retries = 0
        except Exception:
            cloudlog.exception("athena.log_handler.exception")
            log_retries += 1

        if log_retries != 0:
            time.sleep(backoff(log_retries))
예제 #6
0
def set_is_uploaded(filename):
    setxattr(filename, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
예제 #7
0
 def _set_is_uploaded(self, filename):
     _debug("%s set to uploaded" % filename)
     setxattr(filename, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)