Commit 56d23da6 authored by ibuler's avatar ibuler

[Update] 修改上传逻辑

parent 4f0c0719
...@@ -4,8 +4,7 @@ env/ ...@@ -4,8 +4,7 @@ env/
*.pyo *.pyo
.access_key .access_key
*.log *.log
logs/* data/*
host_rsa_key host_rsa_key
sessions/*
coco.pid coco.pid
config.yml config.yml
...@@ -11,8 +11,6 @@ import signal ...@@ -11,8 +11,6 @@ import signal
import copy import copy
from collections import defaultdict from collections import defaultdict
import psutil
from .conf import config from .conf import config
from .sshd import SSHServer from .sshd import SSHServer
from .httpd import HttpServer from .httpd import HttpServer
...@@ -133,41 +131,43 @@ class Coco: ...@@ -133,41 +131,43 @@ class Coco:
thread.start() thread.start()
def monitor_sessions_replay(self): def monitor_sessions_replay(self):
interval = 10 interval = 60 * 60 * 5
log_dir = os.path.join(config['LOG_DIR']) replay_dir = os.path.join(config.REPLAY_DIR)
max_try = 5 max_try = 5
upload_failed = defaultdict(int) upload_failed = defaultdict(int)
def func(): def func():
while not self.stop_evt.is_set(): while not self.stop_evt.is_set():
for filename in os.listdir(log_dir): for d in os.listdir(replay_dir):
suffix = filename.split('.')[-1] date_path = os.path.join(replay_dir, d)
if suffix != 'gz': for filename in os.listdir(date_path):
continue suffix = filename.split('.')[-1]
session_id = filename.split('.')[0] if suffix != 'gz':
if len(session_id) != 36: continue
continue session_id = filename.split('.')[0]
if len(session_id) != 36:
full_path = os.path.join(log_dir, filename) continue
stat = os.stat(full_path)
# 是否是一天前的,因为现在多个coco共享了日志目录, full_path = os.path.join(date_path, filename)
# 不能单纯判断session是否关闭 stat = os.stat(full_path)
if stat.st_mtime > time.time() - 24*60*60: # 是否是一天前的,因为现在多个coco共享了日志目录,
continue # 不能单纯判断session是否关闭
# 失败次数过多 if stat.st_mtime > time.time() - 24*60*60:
if session_id in upload_failed \ continue
and upload_failed[session_id] >= max_try: # 失败次数过多
continue if session_id in upload_failed \
recorder = get_replay_recorder() and upload_failed[session_id] >= max_try:
recorder.file_path = full_path continue
ok = recorder.upload_replay(session_id, 1) recorder = get_replay_recorder()
if ok: recorder.file_path = full_path
upload_failed.pop(session_id, None) recorder.session_id = session_id
elif not ok and os.path.getsize(full_path) == 0: recorder.target = os.path.join(d, filename)
os.unlink(full_path) ok, msg = recorder.upload_replay()
else: if ok:
upload_failed[session_id] += 1 upload_failed.pop(session_id, None)
time.sleep(1) else:
upload_failed[session_id] += 1
time.sleep(1)
time.sleep(interval) time.sleep(interval)
thread = threading.Thread(target=func) thread = threading.Thread(target=func)
thread.start() thread.start()
......
...@@ -332,6 +332,7 @@ defaults = { ...@@ -332,6 +332,7 @@ defaults = {
'SECRET_KEY': 'SDK29K03%MM0ksf&#2', 'SECRET_KEY': 'SDK29K03%MM0ksf&#2',
'LOG_LEVEL': 'INFO', 'LOG_LEVEL': 'INFO',
'LOG_DIR': os.path.join(root_path, 'data', 'logs'), 'LOG_DIR': os.path.join(root_path, 'data', 'logs'),
'REPLAY_DIR': os.path.join(root_path, 'data', 'replays'),
'ASSET_LIST_SORT_BY': 'hostname', # hostname, ip 'ASSET_LIST_SORT_BY': 'hostname', # hostname, ip
'PASSWORD_AUTH': True, 'PASSWORD_AUTH': True,
'PUBLIC_KEY_AUTH': True, 'PUBLIC_KEY_AUTH': True,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
import threading import threading
import datetime
import time import time
import os import os
import gzip import gzip
...@@ -22,14 +23,21 @@ BUF_SIZE = 1024 ...@@ -22,14 +23,21 @@ BUF_SIZE = 1024
class ReplayRecorder(object): class ReplayRecorder(object):
time_start = None time_start = None
target = None
storage = None storage = None
session_id = None
filename = None
file = None
file_path = None
def __init__(self): def __init__(self):
super(ReplayRecorder, self).__init__()
self.file = None
self.file_path = None
self.get_storage() self.get_storage()
def get_storage(self):
conf = deepcopy(config["REPLAY_STORAGE"])
conf["SERVICE"] = app_service
self.storage = jms_storage.get_object_storage(conf)
def record(self, data): def record(self, data):
""" """
:param data: :param data:
...@@ -47,49 +55,56 @@ class ReplayRecorder(object): ...@@ -47,49 +55,56 @@ class ReplayRecorder(object):
def session_start(self, session_id): def session_start(self, session_id):
self.time_start = time.time() self.time_start = time.time()
filename = session_id + '.replay.gz' self.session_id = session_id
self.file_path = os.path.join(config['LOG_DIR'], filename) self.filename = session_id + '.replay.gz'
date = datetime.datetime.utcnow().strftime('%Y-%m-%d')
self.target = date + '/' + self.filename
replay_dir = os.path.join(config.REPLAY_DIR, date)
if not os.path.isdir(replay_dir):
os.makedirs(replay_dir, exist_ok=True)
self.file_path = os.path.join(replay_dir, self.filename)
self.file = gzip.open(self.file_path, 'at') self.file = gzip.open(self.file_path, 'at')
self.file.write('{') self.file.write('{')
def session_end(self, session_id): def session_end(self, session_id):
self.file.write('"0":""}') self.file.write('"0":""}')
self.file.close() self.file.close()
self.upload_replay(session_id) self.upload_replay_some_times()
def get_storage(self):
conf = deepcopy(config["REPLAY_STORAGE"])
conf["SERVICE"] = app_service
self.storage = jms_storage.get_object_storage(conf)
def upload_replay(self, session_id, times=3): def upload_replay_some_times(self, times=3):
# 如果上传OSS、S3失败则尝试上传到服务器
if times < 1: if times < 1:
if self.storage.type == 'jms': if self.storage.type == 'jms':
return False return False
else: self.storage = jms_storage.JMSReplayStorage(
self.storage = jms_storage.JMSReplayStorage( {"SERVICE": app_service}
{"SERVICE": app_service} )
) self.upload_replay_some_times(times=3)
self.upload_replay(session_id, times=3)
ok, msg = self.push_to_storage(session_id) ok, msg = self.upload_replay()
if not ok: if not ok:
msg = 'Failed push replay file {}: {}, try again {}'.format( msg = 'Failed push replay file {}: {}, try again {}'.format(
session_id, msg, times self.filename, msg, times
) )
logger.warn(msg) logger.warn(msg)
self.upload_replay(session_id, times-1) self.upload_replay_some_times(times - 1)
else: else:
msg = 'Success push replay file: {}'.format(session_id) msg = 'Success push replay file: {}'.format(self.session_id)
logger.debug(msg) logger.debug(msg)
self.finish_replay(3, session_id)
os.unlink(self.file_path)
return True return True
def push_to_storage(self, session_id): def upload_replay(self):
dt = time.strftime('%Y-%m-%d', time.localtime(self.time_start)) # 如果文件为空就直接删除
target = dt + '/' + session_id + '.replay.gz' if not os.path.isfile(self.file_path):
return self.storage.upload(self.file_path, target) return False, 'Not found the file: {}'.format(self.file_path)
if os.path.getsize(self.file_path) == 0:
os.unlink(self.file_path)
return True, ''
ok, msg = self.storage.upload(self.file_path, self.target)
if ok:
self.finish_replay(3, self.session_id)
os.unlink(self.file_path)
return ok, msg
def finish_replay(self, times, session_id): def finish_replay(self, times, session_id):
if times < 1: if times < 1:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment