Esempio n. 1
0
    def list_log_streams(self, next_token: str = None):
        """
        List image builder's logs.

        :param next_token: Token for paginated requests.
        :returns ListLogsResponse
        """
        try:
            log_streams = []
            if AWSApi.instance().logs.log_group_exists(self._log_group_name):
                LOGGER.debug("Listing log streams from log group %s", self._log_group_name)
                log_stream_resp = AWSApi.instance().logs.describe_log_streams(
                    log_group_name=self._log_group_name, next_token=next_token
                )
                log_streams.extend(log_stream_resp["logStreams"])
                next_token = log_stream_resp.get("nextToken")
            else:
                LOGGER.debug("Log Group %s doesn't exist.", self._log_group_name)
                raise NotFoundImageBuilderActionError(
                    ("Unable to find image logs, please double check if image id=" f"{self.image_id} is correct.")
                )

            return LogStreams(log_streams, next_token)

        except AWSClientError as e:
            raise ImageBuilderActionError(f"Unexpected error when retrieving image's logs: {e}")
Esempio n. 2
0
    def list_log_streams(self,
                         filters: List[str] = None,
                         next_token: str = None):
        """
        List cluster's logs.

        :param next_token: Token for paginated requests.
        :param filters: Filters in the format Name=name,Values=value1,value2
        Accepted filters are: private_dns_name, node_type==HeadNode
        :returns a dict with the structure {"logStreams": [], "stackEventsStream": {}}
        """
        try:
            # check stack
            if not AWSApi.instance().cfn.stack_exists(self.stack_name):
                raise NotFoundClusterActionError(
                    f"Cluster {self.name} does not exist.")

            log_streams = []

            LOGGER.debug("Listing log streams from log group %s",
                         self.stack.log_group_name)
            if self.stack.log_group_name:
                list_logs_filters = self._init_list_logs_filters(filters)
                log_stream_resp = AWSApi.instance().logs.describe_log_streams(
                    log_group_name=self.stack.log_group_name,
                    log_stream_name_prefix=list_logs_filters.log_stream_prefix,
                    next_token=next_token,
                )
                log_streams.extend(log_stream_resp["logStreams"])
                next_token = log_stream_resp.get("nextToken")
            else:
                LOGGER.debug(
                    "CloudWatch logging is not enabled for cluster %s.",
                    self.name)
                raise BadRequestClusterActionError(
                    f"CloudWatch logging is not enabled for cluster {self.name}."
                )

            return LogStreams(log_streams, next_token)

        except AWSClientError as e:
            raise _cluster_error_mapper(
                e, f"Unexpected error when retrieving cluster's logs: {e}")
    def test_execute(self, mocker, set_env, args):
        logs = LogStreams()
        logs.log_streams = [
            {
                "logStreamName":
                "ip-10-0-0-102.i-0717e670ad2549e72.cfn-init",
                "creationTime":
                1622802842228,
                "firstEventTimestamp":
                1622802790248,
                "lastEventTimestamp":
                1622802893126,
                "lastIngestionTime":
                1622802903119,
                "uploadSequenceToken":
                "4961...",
                "arn":
                ("arn:aws:logs:eu-west-1:111:log-group:/aws/parallelcluster/"
                 "test22-202106041223:log-stream:ip-10-0-0-102.i-0717e670ad2549e72.cfn-init"
                 ),
                "storedBytes":
                0,
            },
            {
                "logStreamName":
                "ip-10-0-0-102.i-0717e670ad2549e72.chef-client",
                "creationTime":
                1622802842207,
                "firstEventTimestamp":
                1622802837114,
                "lastEventTimestamp":
                1622802861226,
                "lastIngestionTime":
                1622802897558,
                "uploadSequenceToken":
                "4962...",
                "arn":
                ("arn:aws:logs:eu-west-1:111:log-group:/aws/parallelcluster/"
                 "test22-202106041223:log-stream:ip-10-0-0-102.i-0717e670ad2549e72.chef-client"
                 ),
                "storedBytes":
                0,
            },
        ]

        logs.next_token = "123-456"

        list_log_streams_mock = mocker.patch(
            "pcluster.api.controllers.image_logs_controller.ImageBuilder.list_log_streams",
            return_value=logs)
        set_env("AWS_DEFAULT_REGION", "us-east-1")

        base_args = ["list-image-log-streams"]
        command = base_args + self._build_cli_args({**REQUIRED_ARGS, **args})

        out = run(command)
        # cfn stack events are not displayed if next-token is passed
        expected_out = [
            {
                "logStreamName":
                "ip-10-0-0-102.i-0717e670ad2549e72.cfn-init",
                "firstEventTimestamp":
                to_iso_timestr(to_utc_datetime(1622802790248)),
                "lastEventTimestamp":
                to_iso_timestr(to_utc_datetime(1622802893126)),
            },
            {
                "logStreamName":
                "ip-10-0-0-102.i-0717e670ad2549e72.chef-client",
                "firstEventTimestamp":
                to_iso_timestr(to_utc_datetime(1622802837114)),
                "lastEventTimestamp":
                to_iso_timestr(to_utc_datetime(1622802861226)),
            },
        ]
        assert_that(out["nextToken"]).is_equal_to(logs.next_token)
        for i in range(len(logs.log_streams)):
            select_keys = {
                "logStreamName", "firstEventTimestamp", "lastEventTimestamp"
            }
            out_select = {
                k: v
                for k, v in out["logStreams"][i].items() if k in select_keys
            }
            assert_that(out_select).is_equal_to(expected_out[i])
        assert_that(list_log_streams_mock.call_args).is_length(2)

        # verify arguments
        kwargs = {"next_token": None}
        kwargs.update(args)
        list_log_streams_mock.assert_called_with(**kwargs)