forked from p15670423/monkey
Integrated an option to download the monkey island log files from the Log page in the web app.
This commit is contained in:
parent
13fa4fa6a4
commit
6aeaf0f857
|
@ -14,6 +14,7 @@ from cc.resources.client_run import ClientRun
|
||||||
from cc.resources.edge import Edge
|
from cc.resources.edge import Edge
|
||||||
from cc.resources.local_run import LocalRun
|
from cc.resources.local_run import LocalRun
|
||||||
from cc.resources.log import Log
|
from cc.resources.log import Log
|
||||||
|
from cc.resources.island_logs import IslandLog
|
||||||
from cc.resources.monkey import Monkey
|
from cc.resources.monkey import Monkey
|
||||||
from cc.resources.monkey_configuration import MonkeyConfiguration
|
from cc.resources.monkey_configuration import MonkeyConfiguration
|
||||||
from cc.resources.monkey_download import MonkeyDownload
|
from cc.resources.monkey_download import MonkeyDownload
|
||||||
|
@ -104,5 +105,6 @@ def init_app(mongo_url):
|
||||||
api.add_resource(Report, '/api/report', '/api/report/')
|
api.add_resource(Report, '/api/report', '/api/report/')
|
||||||
api.add_resource(TelemetryFeed, '/api/telemetry-feed', '/api/telemetry-feed/')
|
api.add_resource(TelemetryFeed, '/api/telemetry-feed', '/api/telemetry-feed/')
|
||||||
api.add_resource(Log, '/api/log', '/api/log/')
|
api.add_resource(Log, '/api/log', '/api/log/')
|
||||||
|
api.add_resource(IslandLog, '/api/log/island/download', '/api/log/island/download/')
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import standard
|
import standard
|
||||||
import aws
|
import aws
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
ENV_DICT = {
|
ENV_DICT = {
|
||||||
'standard': standard.StandardEnvironment,
|
'standard': standard.StandardEnvironment,
|
||||||
'aws': aws.AwsEnvironment
|
'aws': aws.AwsEnvironment
|
||||||
|
@ -19,5 +23,5 @@ try:
|
||||||
__env_type = load_env_from_file()
|
__env_type = load_env_from_file()
|
||||||
env = ENV_DICT[__env_type]()
|
env = ENV_DICT[__env_type]()
|
||||||
except Exception:
|
except Exception:
|
||||||
print('Failed initializing environment: %s' % __env_type)
|
logger.error('Failed initializing environment', exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -3,6 +3,9 @@ import json
|
||||||
import logging.config
|
import logging.config
|
||||||
|
|
||||||
|
|
||||||
|
__author__ = 'Maor.Rayzin'
|
||||||
|
|
||||||
|
|
||||||
def json_setup_logging(default_path='logging.json', default_level=logging.INFO, env_key='LOG_CFG'):
|
def json_setup_logging(default_path='logging.json', default_level=logging.INFO, env_key='LOG_CFG'):
|
||||||
"""
|
"""
|
||||||
Setup the logging configuration
|
Setup the logging configuration
|
||||||
|
|
|
@ -38,6 +38,6 @@
|
||||||
|
|
||||||
"root": {
|
"root": {
|
||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"handlers": ["console", "info_file_handler", "error_file_handler"]
|
"handlers": ["console", "info_file_handler"]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import flask_restful
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from cc.auth import jwt_required
|
||||||
|
from cc.services.island_logs import IslandLogService
|
||||||
|
|
||||||
|
__author__ = "Maor.Rayzin"
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class IslandLog(flask_restful.Resource):
|
||||||
|
@jwt_required()
|
||||||
|
def get(self):
|
||||||
|
try:
|
||||||
|
return IslandLogService.get_log_file()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error('Monkey Island logs failed to download', exc_info=True)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
import copy
|
import copy
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -17,6 +18,9 @@ from cc.encryptor import encryptor
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Telemetry(flask_restful.Resource):
|
class Telemetry(flask_restful.Resource):
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get(self, **kw):
|
def get(self, **kw):
|
||||||
|
@ -52,10 +56,9 @@ class Telemetry(flask_restful.Resource):
|
||||||
if telem_type in TELEM_PROCESS_DICT:
|
if telem_type in TELEM_PROCESS_DICT:
|
||||||
TELEM_PROCESS_DICT[telem_type](telemetry_json)
|
TELEM_PROCESS_DICT[telem_type](telemetry_json)
|
||||||
else:
|
else:
|
||||||
print('Got unknown type of telemetry: %s' % telem_type)
|
logger.info('Got unknown type of telemetry: %s' % telem_type)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("Exception caught while processing telemetry: %s" % str(ex))
|
logger.error("Exception caught while processing telemetry", exc_info=True)
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
telem_id = mongo.db.telemetry.insert(telemetry_json)
|
telem_id = mongo.db.telemetry.insert(telemetry_json)
|
||||||
return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
|
return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import logging
|
||||||
|
__author__ = "Maor.Rayzin"
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class IslandLogService:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_log_file():
|
||||||
|
"""
|
||||||
|
This static function is a helper function for the monkey island log download function.
|
||||||
|
It finds the logger handlers and checks if one of them is a fileHandler of any kind by checking if the handler
|
||||||
|
has the property handler.baseFilename.
|
||||||
|
:return:
|
||||||
|
a dict with the log file content.
|
||||||
|
"""
|
||||||
|
logger_handlers = logger.parent.handlers
|
||||||
|
for handler in logger_handlers:
|
||||||
|
if hasattr(handler, 'baseFilename'):
|
||||||
|
logger.info('Log file found: {0}'.format(handler.baseFilename))
|
||||||
|
log_file_path = handler.baseFilename
|
||||||
|
with open(log_file_path, 'rt') as f:
|
||||||
|
log_file = f.read()
|
||||||
|
return {
|
||||||
|
'log_file': log_file
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warning('No log file could be found, check logger config.')
|
||||||
|
return None
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Col} from 'react-bootstrap';
|
import {Button, Col} from 'react-bootstrap';
|
||||||
import JSONTree from 'react-json-tree'
|
import JSONTree from 'react-json-tree'
|
||||||
import {DataTable} from 'react-data-components';
|
import {DataTable} from 'react-data-components';
|
||||||
import AuthComponent from '../AuthComponent';
|
import AuthComponent from '../AuthComponent';
|
||||||
|
import download from 'downloadjs'
|
||||||
|
|
||||||
const renderJson = (val) => <JSONTree data={val} level={1} theme="eighties" invertTheme={true} />;
|
const renderJson = (val) => <JSONTree data={val} level={1} theme="eighties" invertTheme={true} />;
|
||||||
const renderTime = (val) => val.split('.')[0];
|
const renderTime = (val) => val.split('.')[0];
|
||||||
|
@ -28,21 +29,47 @@ class TelemetryPageComponent extends AuthComponent {
|
||||||
.then(res => this.setState({data: res.objects}));
|
.then(res => this.setState({data: res.objects}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
downloadIslandLog = () => {
|
||||||
|
this.authFetch('/api/log/island/download')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(res => {
|
||||||
|
let filename = 'Island_log'
|
||||||
|
let logContent = (res['log_file']);
|
||||||
|
download(logContent, filename, 'text/plain');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Col xs={12} lg={8}>
|
<div>
|
||||||
<h1 className="page-title">Log</h1>
|
<div>
|
||||||
<div className="data-table-container">
|
<Col xs={12} lg={8}>
|
||||||
<DataTable
|
<h1 className="page-title">Log</h1>
|
||||||
keys="name"
|
<div className="data-table-container">
|
||||||
columns={columns}
|
<DataTable
|
||||||
initialData={this.state.data}
|
keys="name"
|
||||||
initialPageLength={20}
|
columns={columns}
|
||||||
initialSortBy={{ prop: 'timestamp', order: 'descending' }}
|
initialData={this.state.data}
|
||||||
pageLengthOptions={[ 20, 50, 100 ]}
|
initialPageLength={20}
|
||||||
/>
|
initialSortBy={{ prop: 'timestamp', order: 'descending' }}
|
||||||
</div>
|
pageLengthOptions={[ 20, 50, 100 ]}
|
||||||
</Col>
|
/>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Col xs={12} lg={8}>
|
||||||
|
<h1 className="page-title"> Monkey Island Logs </h1>
|
||||||
|
<div className="text-center" style={{marginBottom: '20px'}}>
|
||||||
|
<p style={{'marginBottom': '2em', 'fontSize': '1.2em'}}> Download Monkey Island internal log file </p>
|
||||||
|
<Button bsSize="large" onClick={()=> {
|
||||||
|
this.downloadIslandLog();
|
||||||
|
}}>
|
||||||
|
<i className="glyphicon glyphicon-download"/> Download </Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue