Run the container.

        Logic is as follows:
        Generate container info (eventually from task definition)
        Start container
        Loop whilst not asked to stop and the container is running.
          Get all logs from container between the last time I checked and now.
        Convert logs into cloudwatch format
        Put logs into cloudwatch

        :return:

def run(self):
        """
        Run the container.

        Logic is as follows:
        Generate container info (eventually from task definition)
        Start container
        Loop whilst not asked to stop and the container is running.
          Get all logs from container between the last time I checked and now.
        Convert logs into cloudwatch format
        Put logs into cloudwatch

        :return:
        """
        try:
            self.job_state = 'PENDING'
            time.sleep(1)

            image = 'alpine:latest'
            cmd = '/bin/sh -c "for a in `seq 1 10`; do echo Hello World; sleep 1; done"'
            name = '{0}-{1}'.format(self.job_name, self.job_id)

            self.job_state = 'RUNNABLE'
            # TODO setup ecs container instance
            time.sleep(1)

            self.job_state = 'STARTING'
            container = self.docker_client.containers.run(
                image, cmd,
                detach=True,
                name=name
            )
            self.job_state = 'RUNNING'
            self.job_started_at = datetime.datetime.now()
            try:
                # Log collection
                logs_stdout = []
                logs_stderr = []
                container.reload()

                # Dodgy hack, we can only check docker logs once a second, but we want to loop more
                # so we can stop if asked to in a quick manner, should all go away if we go async
                # There also be some dodgyness when sending an integer to docker logs and some
                # events seem to be duplicated.
                now = datetime.datetime.now()
                i = 1
                while container.status == 'running' and not self.stop:
                    time.sleep(0.15)
                    if i % 10 == 0:
                        logs_stderr.extend(container.logs(stdout=False, stderr=True, timestamps=True, since=datetime2int(now)).decode().split('\n'))
                        logs_stdout.extend(container.logs(stdout=True, stderr=False, timestamps=True, since=datetime2int(now)).decode().split('\n'))
                        now = datetime.datetime.now()
                        container.reload()
                    i += 1

                # Container should be stopped by this point... unless asked to stop
                if container.status == 'running':
                    container.kill()

                self.job_stopped_at = datetime.datetime.now()
                # Get final logs
                logs_stderr.extend(container.logs(stdout=False, stderr=True, timestamps=True, since=datetime2int(now)).decode().split('\n'))
                logs_stdout.extend(container.logs(stdout=True, stderr=False, timestamps=True, since=datetime2int(now)).decode().split('\n'))

                self.job_state = 'SUCCEEDED' if not self.stop else 'FAILED'

                # Process logs
                logs_stdout = [x for x in logs_stdout if len(x) > 0]
                logs_stderr = [x for x in logs_stderr if len(x) > 0]
                logs = []
                for line in logs_stdout + logs_stderr:
                    date, line = line.split(' ', 1)
                    date = dateutil.parser.parse(date)
                    date = int(date.timestamp())
                    logs.append({'timestamp': date, 'message': line.strip()})

                # Send to cloudwatch
                log_group = '/aws/batch/job'
                stream_name = '{0}/default/{1}'.format(self.job_definition.name, self.job_id)
                self.log_stream_name = stream_name
                self._log_backend.ensure_log_group(log_group, None)
                self._log_backend.create_log_stream(log_group, stream_name)
                self._log_backend.put_log_events(log_group, stream_name, logs, None)

            except Exception as err:
                logger.error('Failed to run AWS Batch container {0}. Error {1}'.format(self.name, err))
                self.job_state = 'FAILED'
                container.kill()
            finally:
                container.remove()
        except Exception as err:
            logger.error('Failed to run AWS Batch container {0}. Error {1}'.format(self.name, err))
            self.job_state = 'FAILED'

        self.job_stopped = True
        self.job_stopped_at = datetime.datetime.now()