private void flush() {
        var drained = 0;
        var logEvents = new ArrayList<InputLogEvent>(AWS_DRAIN_LIMIT);
        do {
            drained = queue.drainTo(logEvents, AWS_DRAIN_LIMIT);
            if (logEvents.isEmpty()) {
                break;
            }
            logEvents.sort(Comparator.comparing(InputLogEvent::timestamp));
            if (lastReportedTimestamp > 0) {
                logEvents = logEvents.stream()
                    .map(event -> {
                        if (event.timestamp() < lastReportedTimestamp) {
                            return event.copy(builder -> builder.timestamp(lastReportedTimestamp));
                        }
                        return event;
                    })
                    .sorted(Comparator.comparing(InputLogEvent::timestamp))
                    .collect(Collectors.toCollection(ArrayList::new));
            }

            lastReportedTimestamp = logEvents.getLast().timestamp();
            val putLogEventsRequest = PutLogEventsRequest.builder().logGroupName(logGroupName).logStreamName(logStreamName).logEvents(logEvents);
            if (StringUtils.isNotBlank(this.sequenceTokenCache)) {
                putLogEventsRequest.sequenceToken(this.sequenceTokenCache);
            }
            try {
                val putLogEventsResult = awsLogsClient.putLogEvents(putLogEventsRequest.build());
                sequenceTokenCache = putLogEventsResult.nextSequenceToken();
            } catch (final DataAlreadyAcceptedException daae) {
                sequenceTokenCache = daae.expectedSequenceToken();
            } catch (final InvalidSequenceTokenException iste) {
                sequenceTokenCache = iste.expectedSequenceToken();
            } catch (final Exception e) {
                org.apereo.cas.util.LoggingUtils.error(LOGGER, e);
            }
            logEvents.clear();
        } while (drained >= AWS_DRAIN_LIMIT);
    }
Create appender cloud watch appender.

@param name                             the name
@param endpoint                         the endpoint
@param awsLogStreamName                 the aws log stream name
@param awsLogGroupName                  the aws log group name
@param awsLogStreamFlushPeriodInSeconds the aws log stream flush period in seconds
@param credentialAccessKey              the credential access key
@param credentialSecretKey              the credential secret key
@param awsLogRegionName                 the aws log region name
@param layout                           the layout
@param createIfNeeded                   whether to create resources if needed
@param createLogGroupIfNeeded           whether to create log group if needed
@param createLogStreamIfNeeded          whether to create log stream if needed
@return the cloud watch appender
support/cas-server-support-aws-cloudwatch/src/main/java/org/apereo/cas/logging/CloudWatchAppender.java