mirror of https://github.com/scrapy/scrapy.git
scrapyd: changed keys used in poller message to _project, _spider, _job, and added link to log file in web ui
This commit is contained in:
parent
df54ed0041
commit
5c4f562ec4
|
|
@ -19,7 +19,7 @@ class Environment(object):
|
|||
self.initenv = initenv
|
||||
|
||||
def get_environment(self, message, slot, eggpath):
|
||||
project = message['project']
|
||||
project = message['_project']
|
||||
env = self.initenv.copy()
|
||||
env['SCRAPY_PROJECT'] = project
|
||||
if eggpath:
|
||||
|
|
@ -32,11 +32,11 @@ class Environment(object):
|
|||
return env
|
||||
|
||||
def _get_log_file(self, message):
|
||||
logsdir = os.path.join(self.logs_dir, message['project'], \
|
||||
message['spider'])
|
||||
logsdir = os.path.join(self.logs_dir, message['_project'], \
|
||||
message['_spider'])
|
||||
if not os.path.exists(logsdir):
|
||||
os.makedirs(logsdir)
|
||||
to_delete = sorted(os.listdir(logsdir), reverse=True)[:-self.logs_to_keep]
|
||||
for x in to_delete:
|
||||
os.remove(os.path.join(logsdir, x))
|
||||
return os.path.join(logsdir, "%s.log" % message['_id'])
|
||||
return os.path.join(logsdir, "%s.log" % message['_job'])
|
||||
|
|
|
|||
|
|
@ -35,9 +35,11 @@ class IPoller(Interface):
|
|||
project that needs to run, or already fired if there was a project
|
||||
waiting to run already.
|
||||
|
||||
The message is a dict containing (at least) the name of the project to
|
||||
be run in the 'project' key. This message will be passed later to
|
||||
IEnvironment.get_environment().
|
||||
The message is a dict containing (at least):
|
||||
* the name of the project to be run in the '_project' key
|
||||
* the name of the spider to be run in the '_spider' key
|
||||
* a unique identifier for this run in the `_job` key
|
||||
This message will be passed later to IEnvironment.get_environment().
|
||||
"""
|
||||
|
||||
def update_projects():
|
||||
|
|
@ -65,9 +67,7 @@ class IEnvironment(Interface):
|
|||
def get_environment(message, slot, eggpath):
|
||||
"""Return the environment variables to use for running the process.
|
||||
|
||||
`message` is the message received from the IPoller.next() augmented to
|
||||
contain (at least) the following keys: project, spider, _id (where
|
||||
_id is a unique identifier for this run)
|
||||
`message` is the message received from the IPoller.next() method
|
||||
`slot` is the Launcher slot where the process will be running.
|
||||
`eggpath` is the path to an eggfile that contains the project code. The
|
||||
`eggpath` may be `None` if no egg was found for the project, in
|
||||
|
|
|
|||
|
|
@ -48,13 +48,15 @@ class Launcher(Service):
|
|||
|
||||
def _spawn_process(self, message, slot):
|
||||
msg = stringify_dict(message, keys_only=False)
|
||||
project = msg['project']
|
||||
project = msg['_project']
|
||||
eggpath = self._get_eggpath(project)
|
||||
args = [sys.executable, '-m', self.egg_runner, 'crawl']
|
||||
args += get_crawl_args(msg)
|
||||
e = self.app.getComponent(IEnvironment)
|
||||
env = e.get_environment(msg, slot, eggpath)
|
||||
pp = ScrapyProcessProtocol(eggpath, slot, project, msg['spider'], msg['_id'])
|
||||
env = stringify_dict(env, keys_only=False)
|
||||
pp = ScrapyProcessProtocol(eggpath, slot, project, msg['_spider'], \
|
||||
msg['_job'], env)
|
||||
pp.deferred.addBoth(self._process_finished, eggpath, slot)
|
||||
reactor.spawnProcess(pp, sys.executable, args=args, env=env)
|
||||
self.processes[slot] = pp
|
||||
|
|
@ -68,7 +70,7 @@ class Launcher(Service):
|
|||
|
||||
class ScrapyProcessProtocol(protocol.ProcessProtocol):
|
||||
|
||||
def __init__(self, eggfile, slot, project, spider, job):
|
||||
def __init__(self, eggfile, slot, project, spider, job, env):
|
||||
self.eggfile = eggfile
|
||||
self.slot = slot
|
||||
self.pid = None
|
||||
|
|
@ -76,6 +78,8 @@ class ScrapyProcessProtocol(protocol.ProcessProtocol):
|
|||
self.spider = spider
|
||||
self.job = job
|
||||
self.start_time = datetime.now()
|
||||
self.env = env
|
||||
self.logfile = env['SCRAPY_LOG_FILE']
|
||||
self.deferred = defer.Deferred()
|
||||
|
||||
def outReceived(self, data):
|
||||
|
|
|
|||
|
|
@ -29,6 +29,6 @@ class QueuePoller(object):
|
|||
|
||||
def _message(self, queue_msg, project):
|
||||
d = queue_msg.copy()
|
||||
d['project'] = project
|
||||
d['spider'] = d.pop('name')
|
||||
d['_project'] = project
|
||||
d['_spider'] = d.pop('name')
|
||||
return d
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class EggStorageTest(unittest.TestCase):
|
|||
verifyObject(IEnvironment, self.environ)
|
||||
|
||||
def test_get_environment_with_eggfile(self):
|
||||
msg = {'project': 'mybot', 'spider': 'myspider', '_id': 'ID'}
|
||||
msg = {'_project': 'mybot', '_spider': 'myspider', '_job': 'ID'}
|
||||
slot = 3
|
||||
env = self.environ.get_environment(msg, slot, '/path/to/file.egg')
|
||||
self.assertEqual(env['SCRAPY_PROJECT'], 'mybot')
|
||||
|
|
@ -32,7 +32,7 @@ class EggStorageTest(unittest.TestCase):
|
|||
self.failIf('SCRAPY_SETTINGS_MODULE' in env)
|
||||
|
||||
def test_get_environment_without_eggfile(self):
|
||||
msg = {'project': 'newbot', 'spider': 'myspider', '_id': 'ID'}
|
||||
msg = {'_project': 'newbot', '_spider': 'myspider', '_job': 'ID'}
|
||||
slot = 3
|
||||
env = self.environ.get_environment(msg, slot, None)
|
||||
self.assertEqual(env['SCRAPY_PROJECT'], 'newbot')
|
||||
|
|
|
|||
|
|
@ -37,5 +37,5 @@ class QueuePollerTest(unittest.TestCase):
|
|||
self.poller.poll()
|
||||
self.queues['mybot1'].pop()
|
||||
self.poller.poll()
|
||||
self.failUnlessEqual(d1.result, {'project': 'mybot1', 'spider': 'spider1'})
|
||||
self.failUnlessEqual(d2.result, {'project': 'mybot2', 'spider': 'spider2'})
|
||||
self.failUnlessEqual(d1.result, {'_project': 'mybot1', '_spider': 'spider1'})
|
||||
self.failUnlessEqual(d2.result, {'_project': 'mybot2', '_spider': 'spider2'})
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ from scrapyd.utils import get_crawl_args
|
|||
class UtilsTest(unittest.TestCase):
|
||||
|
||||
def test_get_crawl_args(self):
|
||||
msg = {'project': 'lolo', 'spider': 'lala'}
|
||||
msg = {'_project': 'lolo', '_spider': 'lala'}
|
||||
self.assertEqual(get_crawl_args(msg), ['lala'])
|
||||
msg = {'project': 'lolo', 'spider': 'lala', 'arg1': u'val1'}
|
||||
msg = {'_project': 'lolo', '_spider': 'lala', 'arg1': u'val1'}
|
||||
cargs = get_crawl_args(msg)
|
||||
self.assertEqual(cargs, ['lala', '-a', 'arg1=val1'])
|
||||
assert all(isinstance(x, str) for x in cargs), cargs
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ def get_crawl_args(message):
|
|||
that will be started for this message
|
||||
"""
|
||||
msg = message.copy()
|
||||
args = [unicode_to_str(msg['spider'])]
|
||||
del msg['project'], msg['spider']
|
||||
args = [unicode_to_str(msg['_spider'])]
|
||||
del msg['_project'], msg['_spider']
|
||||
for k, v in stringify_dict(msg, keys_only=False).items():
|
||||
args += ['-a']
|
||||
args += ['%s=%s' % (k, v)]
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Schedule(WsResource):
|
|||
project = args.pop('project')
|
||||
spider = args.pop('spider')
|
||||
jobid = uuid.uuid1().hex
|
||||
args['_id'] = jobid
|
||||
args['_job'] = jobid
|
||||
self.root.scheduler.schedule(project, spider, **args)
|
||||
jobids = {spider: jobid}
|
||||
return {"status": "ok", "jobs": jobids}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ class Home(resource.Resource):
|
|||
<body>
|
||||
<h1>Scrapyd</h1>
|
||||
<ul>
|
||||
<li><a href="procmon">Process monitor</a></li>
|
||||
<li><a href="logs/">Logs</li>
|
||||
<li><a href="/procmon">Process monitor</a></li>
|
||||
<li><a href="/logs/">Logs</li>
|
||||
<li><a href="http://doc.scrapy.org/topics/scrapyd.html">Documentation</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
|
|
@ -79,13 +79,14 @@ class ProcessMonitor(resource.Resource):
|
|||
s += "<p><a href='..'>Go back</a></p>"
|
||||
s += "<table border='1'>"
|
||||
s += "<tr>"
|
||||
s += "<th>Project</th><th>Spider</th><th>Job</th><th>PID</th><th>Runtime</th>"
|
||||
s += "<th>Project</th><th>Spider</th><th>Job</th><th>PID</th><th>Runtime</th><th>Log</th>"
|
||||
s += "</tr>"
|
||||
for p in self.root.launcher.processes.values():
|
||||
s += "<tr>"
|
||||
for a in ['project', 'spider', 'job', 'pid']:
|
||||
s += "<td>%s</td>" % getattr(p, a)
|
||||
s += "<td>%s</td>" % (datetime.now() - p.start_time)
|
||||
s += "<td><a href='/logs/%s/%s/%s.log'>Log</a></td>" % (p.project, p.spider, p.job)
|
||||
s += "</tr>"
|
||||
s += "</table>"
|
||||
s += "</body>"
|
||||
|
|
|
|||
Loading…
Reference in New Issue