// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.

// Package cloudwatchlogs provides a client for Amazon CloudWatch Logs.
package cloudwatchlogs

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/private/protocol"
	"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
)

const opCancelExportTask = "CancelExportTask"

// CancelExportTaskRequest generates a request for the CancelExportTask operation.
func (c *CloudWatchLogs) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) {
	op := &request.Operation{
		Name:       opCancelExportTask,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CancelExportTaskInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &CancelExportTaskOutput{}
	req.Data = output
	return
}

// Cancels an export task if it is in PENDING or RUNNING state.
func (c *CloudWatchLogs) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskOutput, error) {
	req, out := c.CancelExportTaskRequest(input)
	err := req.Send()
	return out, err
}

const opCreateExportTask = "CreateExportTask"

// CreateExportTaskRequest generates a request for the CreateExportTask operation.
func (c *CloudWatchLogs) CreateExportTaskRequest(input *CreateExportTaskInput) (req *request.Request, output *CreateExportTaskOutput) {
	op := &request.Operation{
		Name:       opCreateExportTask,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateExportTaskInput{}
	}

	req = c.newRequest(op, input, output)
	output = &CreateExportTaskOutput{}
	req.Data = output
	return
}

// Creates an ExportTask which allows you to efficiently export data from a
// Log Group to your Amazon S3 bucket.
//
//  This is an asynchronous call. If all the required information is provided,
// this API will initiate an export task and respond with the task Id. Once
// started, DescribeExportTasks can be used to get the status of an export task.
// You can only have one active (RUNNING or PENDING) export task at a time,
// per account.
//
//  You can export logs from multiple log groups or multiple time ranges to
// the same Amazon S3 bucket. To separate out log data for each export task,
// you can specify a prefix that will be used as the Amazon S3 key prefix for
// all exported objects.
func (c *CloudWatchLogs) CreateExportTask(input *CreateExportTaskInput) (*CreateExportTaskOutput, error) {
	req, out := c.CreateExportTaskRequest(input)
	err := req.Send()
	return out, err
}

const opCreateLogGroup = "CreateLogGroup"

// CreateLogGroupRequest generates a request for the CreateLogGroup operation.
func (c *CloudWatchLogs) CreateLogGroupRequest(input *CreateLogGroupInput) (req *request.Request, output *CreateLogGroupOutput) {
	op := &request.Operation{
		Name:       opCreateLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLogGroupInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &CreateLogGroupOutput{}
	req.Data = output
	return
}

// Creates a new log group with the specified name. The name of the log group
// must be unique within a region for an AWS account. You can create up to 500
// log groups per account.
//
//  You must use the following guidelines when naming a log group:  Log group
// names can be between 1 and 512 characters long. Allowed characters are a-z,
// A-Z, 0-9, '_' (underscore), '-' (hyphen), '/' (forward slash), and '.' (period).
func (c *CloudWatchLogs) CreateLogGroup(input *CreateLogGroupInput) (*CreateLogGroupOutput, error) {
	req, out := c.CreateLogGroupRequest(input)
	err := req.Send()
	return out, err
}

const opCreateLogStream = "CreateLogStream"

// CreateLogStreamRequest generates a request for the CreateLogStream operation.
func (c *CloudWatchLogs) CreateLogStreamRequest(input *CreateLogStreamInput) (req *request.Request, output *CreateLogStreamOutput) {
	op := &request.Operation{
		Name:       opCreateLogStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLogStreamInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &CreateLogStreamOutput{}
	req.Data = output
	return
}

// Creates a new log stream in the specified log group. The name of the log
// stream must be unique within the log group. There is no limit on the number
// of log streams that can exist in a log group.
//
//  You must use the following guidelines when naming a log stream:  Log stream
// names can be between 1 and 512 characters long. The ':' colon character is
// not allowed.
func (c *CloudWatchLogs) CreateLogStream(input *CreateLogStreamInput) (*CreateLogStreamOutput, error) {
	req, out := c.CreateLogStreamRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteDestination = "DeleteDestination"

// DeleteDestinationRequest generates a request for the DeleteDestination operation.
func (c *CloudWatchLogs) DeleteDestinationRequest(input *DeleteDestinationInput) (req *request.Request, output *DeleteDestinationOutput) {
	op := &request.Operation{
		Name:       opDeleteDestination,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteDestinationInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteDestinationOutput{}
	req.Data = output
	return
}

// Deletes the destination with the specified name and eventually disables all
// the subscription filters that publish to it. This will not delete the physical
// resource encapsulated by the destination.
func (c *CloudWatchLogs) DeleteDestination(input *DeleteDestinationInput) (*DeleteDestinationOutput, error) {
	req, out := c.DeleteDestinationRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteLogGroup = "DeleteLogGroup"

// DeleteLogGroupRequest generates a request for the DeleteLogGroup operation.
func (c *CloudWatchLogs) DeleteLogGroupRequest(input *DeleteLogGroupInput) (req *request.Request, output *DeleteLogGroupOutput) {
	op := &request.Operation{
		Name:       opDeleteLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLogGroupInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteLogGroupOutput{}
	req.Data = output
	return
}

// Deletes the log group with the specified name and permanently deletes all
// the archived log events associated with it.
func (c *CloudWatchLogs) DeleteLogGroup(input *DeleteLogGroupInput) (*DeleteLogGroupOutput, error) {
	req, out := c.DeleteLogGroupRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteLogStream = "DeleteLogStream"

// DeleteLogStreamRequest generates a request for the DeleteLogStream operation.
func (c *CloudWatchLogs) DeleteLogStreamRequest(input *DeleteLogStreamInput) (req *request.Request, output *DeleteLogStreamOutput) {
	op := &request.Operation{
		Name:       opDeleteLogStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLogStreamInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteLogStreamOutput{}
	req.Data = output
	return
}

// Deletes a log stream and permanently deletes all the archived log events
// associated with it.
func (c *CloudWatchLogs) DeleteLogStream(input *DeleteLogStreamInput) (*DeleteLogStreamOutput, error) {
	req, out := c.DeleteLogStreamRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteMetricFilter = "DeleteMetricFilter"

// DeleteMetricFilterRequest generates a request for the DeleteMetricFilter operation.
func (c *CloudWatchLogs) DeleteMetricFilterRequest(input *DeleteMetricFilterInput) (req *request.Request, output *DeleteMetricFilterOutput) {
	op := &request.Operation{
		Name:       opDeleteMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteMetricFilterInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteMetricFilterOutput{}
	req.Data = output
	return
}

// Deletes a metric filter associated with the specified log group.
func (c *CloudWatchLogs) DeleteMetricFilter(input *DeleteMetricFilterInput) (*DeleteMetricFilterOutput, error) {
	req, out := c.DeleteMetricFilterRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteRetentionPolicy = "DeleteRetentionPolicy"

// DeleteRetentionPolicyRequest generates a request for the DeleteRetentionPolicy operation.
func (c *CloudWatchLogs) DeleteRetentionPolicyRequest(input *DeleteRetentionPolicyInput) (req *request.Request, output *DeleteRetentionPolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteRetentionPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteRetentionPolicyInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteRetentionPolicyOutput{}
	req.Data = output
	return
}

// Deletes the retention policy of the specified log group. Log events would
// not expire if they belong to log groups without a retention policy.
func (c *CloudWatchLogs) DeleteRetentionPolicy(input *DeleteRetentionPolicyInput) (*DeleteRetentionPolicyOutput, error) {
	req, out := c.DeleteRetentionPolicyRequest(input)
	err := req.Send()
	return out, err
}

const opDeleteSubscriptionFilter = "DeleteSubscriptionFilter"

// DeleteSubscriptionFilterRequest generates a request for the DeleteSubscriptionFilter operation.
func (c *CloudWatchLogs) DeleteSubscriptionFilterRequest(input *DeleteSubscriptionFilterInput) (req *request.Request, output *DeleteSubscriptionFilterOutput) {
	op := &request.Operation{
		Name:       opDeleteSubscriptionFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteSubscriptionFilterInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &DeleteSubscriptionFilterOutput{}
	req.Data = output
	return
}

// Deletes a subscription filter associated with the specified log group.
func (c *CloudWatchLogs) DeleteSubscriptionFilter(input *DeleteSubscriptionFilterInput) (*DeleteSubscriptionFilterOutput, error) {
	req, out := c.DeleteSubscriptionFilterRequest(input)
	err := req.Send()
	return out, err
}

const opDescribeDestinations = "DescribeDestinations"

// DescribeDestinationsRequest generates a request for the DescribeDestinations operation.
func (c *CloudWatchLogs) DescribeDestinationsRequest(input *DescribeDestinationsInput) (req *request.Request, output *DescribeDestinationsOutput) {
	op := &request.Operation{
		Name:       opDescribeDestinations,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeDestinationsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeDestinationsOutput{}
	req.Data = output
	return
}

// Returns all the destinations that are associated with the AWS account making
// the request. The list returned in the response is ASCII-sorted by destination
// name.
//
//  By default, this operation returns up to 50 destinations. If there are
// more destinations to list, the response would contain a nextToken value in
// the response body. You can also limit the number of destinations returned
// in the response by specifying the limit parameter in the request.
func (c *CloudWatchLogs) DescribeDestinations(input *DescribeDestinationsInput) (*DescribeDestinationsOutput, error) {
	req, out := c.DescribeDestinationsRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) DescribeDestinationsPages(input *DescribeDestinationsInput, fn func(p *DescribeDestinationsOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.DescribeDestinationsRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*DescribeDestinationsOutput), lastPage)
	})
}

const opDescribeExportTasks = "DescribeExportTasks"

// DescribeExportTasksRequest generates a request for the DescribeExportTasks operation.
func (c *CloudWatchLogs) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) {
	op := &request.Operation{
		Name:       opDescribeExportTasks,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeExportTasksInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeExportTasksOutput{}
	req.Data = output
	return
}

// Returns all the export tasks that are associated with the AWS account making
// the request. The export tasks can be filtered based on TaskId or TaskStatus.
//
//  By default, this operation returns up to 50 export tasks that satisfy the
// specified filters. If there are more export tasks to list, the response would
// contain a nextToken value in the response body. You can also limit the number
// of export tasks returned in the response by specifying the limit parameter
// in the request.
func (c *CloudWatchLogs) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExportTasksOutput, error) {
	req, out := c.DescribeExportTasksRequest(input)
	err := req.Send()
	return out, err
}

const opDescribeLogGroups = "DescribeLogGroups"

// DescribeLogGroupsRequest generates a request for the DescribeLogGroups operation.
func (c *CloudWatchLogs) DescribeLogGroupsRequest(input *DescribeLogGroupsInput) (req *request.Request, output *DescribeLogGroupsOutput) {
	op := &request.Operation{
		Name:       opDescribeLogGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeLogGroupsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeLogGroupsOutput{}
	req.Data = output
	return
}

// Returns all the log groups that are associated with the AWS account making
// the request. The list returned in the response is ASCII-sorted by log group
// name.
//
//  By default, this operation returns up to 50 log groups. If there are more
// log groups to list, the response would contain a nextToken value in the response
// body. You can also limit the number of log groups returned in the response
// by specifying the limit parameter in the request.
func (c *CloudWatchLogs) DescribeLogGroups(input *DescribeLogGroupsInput) (*DescribeLogGroupsOutput, error) {
	req, out := c.DescribeLogGroupsRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) DescribeLogGroupsPages(input *DescribeLogGroupsInput, fn func(p *DescribeLogGroupsOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.DescribeLogGroupsRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*DescribeLogGroupsOutput), lastPage)
	})
}

const opDescribeLogStreams = "DescribeLogStreams"

// DescribeLogStreamsRequest generates a request for the DescribeLogStreams operation.
func (c *CloudWatchLogs) DescribeLogStreamsRequest(input *DescribeLogStreamsInput) (req *request.Request, output *DescribeLogStreamsOutput) {
	op := &request.Operation{
		Name:       opDescribeLogStreams,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeLogStreamsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeLogStreamsOutput{}
	req.Data = output
	return
}

// Returns all the log streams that are associated with the specified log group.
// The list returned in the response is ASCII-sorted by log stream name.
//
//  By default, this operation returns up to 50 log streams. If there are more
// log streams to list, the response would contain a nextToken value in the
// response body. You can also limit the number of log streams returned in the
// response by specifying the limit parameter in the request. This operation
// has a limit of five transactions per second, after which transactions are
// throttled.
func (c *CloudWatchLogs) DescribeLogStreams(input *DescribeLogStreamsInput) (*DescribeLogStreamsOutput, error) {
	req, out := c.DescribeLogStreamsRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) DescribeLogStreamsPages(input *DescribeLogStreamsInput, fn func(p *DescribeLogStreamsOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.DescribeLogStreamsRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*DescribeLogStreamsOutput), lastPage)
	})
}

const opDescribeMetricFilters = "DescribeMetricFilters"

// DescribeMetricFiltersRequest generates a request for the DescribeMetricFilters operation.
func (c *CloudWatchLogs) DescribeMetricFiltersRequest(input *DescribeMetricFiltersInput) (req *request.Request, output *DescribeMetricFiltersOutput) {
	op := &request.Operation{
		Name:       opDescribeMetricFilters,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeMetricFiltersInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeMetricFiltersOutput{}
	req.Data = output
	return
}

// Returns all the metrics filters associated with the specified log group.
// The list returned in the response is ASCII-sorted by filter name.
//
//  By default, this operation returns up to 50 metric filters. If there are
// more metric filters to list, the response would contain a nextToken value
// in the response body. You can also limit the number of metric filters returned
// in the response by specifying the limit parameter in the request.
func (c *CloudWatchLogs) DescribeMetricFilters(input *DescribeMetricFiltersInput) (*DescribeMetricFiltersOutput, error) {
	req, out := c.DescribeMetricFiltersRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) DescribeMetricFiltersPages(input *DescribeMetricFiltersInput, fn func(p *DescribeMetricFiltersOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.DescribeMetricFiltersRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*DescribeMetricFiltersOutput), lastPage)
	})
}

const opDescribeSubscriptionFilters = "DescribeSubscriptionFilters"

// DescribeSubscriptionFiltersRequest generates a request for the DescribeSubscriptionFilters operation.
func (c *CloudWatchLogs) DescribeSubscriptionFiltersRequest(input *DescribeSubscriptionFiltersInput) (req *request.Request, output *DescribeSubscriptionFiltersOutput) {
	op := &request.Operation{
		Name:       opDescribeSubscriptionFilters,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeSubscriptionFiltersInput{}
	}

	req = c.newRequest(op, input, output)
	output = &DescribeSubscriptionFiltersOutput{}
	req.Data = output
	return
}

// Returns all the subscription filters associated with the specified log group.
// The list returned in the response is ASCII-sorted by filter name.
//
//  By default, this operation returns up to 50 subscription filters. If there
// are more subscription filters to list, the response would contain a nextToken
// value in the response body. You can also limit the number of subscription
// filters returned in the response by specifying the limit parameter in the
// request.
func (c *CloudWatchLogs) DescribeSubscriptionFilters(input *DescribeSubscriptionFiltersInput) (*DescribeSubscriptionFiltersOutput, error) {
	req, out := c.DescribeSubscriptionFiltersRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) DescribeSubscriptionFiltersPages(input *DescribeSubscriptionFiltersInput, fn func(p *DescribeSubscriptionFiltersOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.DescribeSubscriptionFiltersRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*DescribeSubscriptionFiltersOutput), lastPage)
	})
}

const opFilterLogEvents = "FilterLogEvents"

// FilterLogEventsRequest generates a request for the FilterLogEvents operation.
func (c *CloudWatchLogs) FilterLogEventsRequest(input *FilterLogEventsInput) (req *request.Request, output *FilterLogEventsOutput) {
	op := &request.Operation{
		Name:       opFilterLogEvents,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &FilterLogEventsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &FilterLogEventsOutput{}
	req.Data = output
	return
}

// Retrieves log events, optionally filtered by a filter pattern from the specified
// log group. You can provide an optional time range to filter the results on
// the event timestamp. You can limit the streams searched to an explicit list
// of logStreamNames.
//
//  By default, this operation returns as much matching log events as can fit
// in a response size of 1MB, up to 10,000 log events, or all the events found
// within a time-bounded scan window. If the response includes a nextToken,
// then there is more data to search, and the search can be resumed with a new
// request providing the nextToken. The response will contain a list of searchedLogStreams
// that contains information about which streams were searched in the request
// and whether they have been searched completely or require further pagination.
// The limit parameter in the request. can be used to specify the maximum number
// of events to return in a page.
func (c *CloudWatchLogs) FilterLogEvents(input *FilterLogEventsInput) (*FilterLogEventsOutput, error) {
	req, out := c.FilterLogEventsRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) FilterLogEventsPages(input *FilterLogEventsInput, fn func(p *FilterLogEventsOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.FilterLogEventsRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*FilterLogEventsOutput), lastPage)
	})
}

const opGetLogEvents = "GetLogEvents"

// GetLogEventsRequest generates a request for the GetLogEvents operation.
func (c *CloudWatchLogs) GetLogEventsRequest(input *GetLogEventsInput) (req *request.Request, output *GetLogEventsOutput) {
	op := &request.Operation{
		Name:       opGetLogEvents,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextForwardToken"},
			LimitToken:      "limit",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &GetLogEventsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &GetLogEventsOutput{}
	req.Data = output
	return
}

// Retrieves log events from the specified log stream. You can provide an optional
// time range to filter the results on the event timestamp.
//
//  By default, this operation returns as much log events as can fit in a response
// size of 1MB, up to 10,000 log events. The response will always include a
// nextForwardToken and a nextBackwardToken in the response body. You can use
// any of these tokens in subsequent GetLogEvents requests to paginate through
// events in either forward or backward direction. You can also limit the number
// of log events returned in the response by specifying the limit parameter
// in the request.
func (c *CloudWatchLogs) GetLogEvents(input *GetLogEventsInput) (*GetLogEventsOutput, error) {
	req, out := c.GetLogEventsRequest(input)
	err := req.Send()
	return out, err
}

func (c *CloudWatchLogs) GetLogEventsPages(input *GetLogEventsInput, fn func(p *GetLogEventsOutput, lastPage bool) (shouldContinue bool)) error {
	page, _ := c.GetLogEventsRequest(input)
	page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
	return page.EachPage(func(p interface{}, lastPage bool) bool {
		return fn(p.(*GetLogEventsOutput), lastPage)
	})
}

const opPutDestination = "PutDestination"

// PutDestinationRequest generates a request for the PutDestination operation.
func (c *CloudWatchLogs) PutDestinationRequest(input *PutDestinationInput) (req *request.Request, output *PutDestinationOutput) {
	op := &request.Operation{
		Name:       opPutDestination,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutDestinationInput{}
	}

	req = c.newRequest(op, input, output)
	output = &PutDestinationOutput{}
	req.Data = output
	return
}

// Creates or updates a Destination. A destination encapsulates a physical resource
// (such as a Kinesis stream) and allows you to subscribe to a real-time stream
// of log events of a different account, ingested through PutLogEvents requests.
// Currently, the only supported physical resource is a Amazon Kinesis stream
// belonging to the same account as the destination.
//
//  A destination controls what is written to its Amazon Kinesis stream through
// an access policy. By default, PutDestination does not set any access policy
// with the destination, which means a cross-account user will not be able to
// call PutSubscriptionFilter against this destination. To enable that, the
// destination owner must call PutDestinationPolicy after PutDestination.
func (c *CloudWatchLogs) PutDestination(input *PutDestinationInput) (*PutDestinationOutput, error) {
	req, out := c.PutDestinationRequest(input)
	err := req.Send()
	return out, err
}

const opPutDestinationPolicy = "PutDestinationPolicy"

// PutDestinationPolicyRequest generates a request for the PutDestinationPolicy operation.
func (c *CloudWatchLogs) PutDestinationPolicyRequest(input *PutDestinationPolicyInput) (req *request.Request, output *PutDestinationPolicyOutput) {
	op := &request.Operation{
		Name:       opPutDestinationPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutDestinationPolicyInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &PutDestinationPolicyOutput{}
	req.Data = output
	return
}

// Creates or updates an access policy associated with an existing Destination.
// An access policy is an IAM policy document (http://docs.aws.amazon.com/IAM/latest/UserGuide/policies_overview.html)
// that is used to authorize claims to register a subscription filter against
// a given destination.
func (c *CloudWatchLogs) PutDestinationPolicy(input *PutDestinationPolicyInput) (*PutDestinationPolicyOutput, error) {
	req, out := c.PutDestinationPolicyRequest(input)
	err := req.Send()
	return out, err
}

const opPutLogEvents = "PutLogEvents"

// PutLogEventsRequest generates a request for the PutLogEvents operation.
func (c *CloudWatchLogs) PutLogEventsRequest(input *PutLogEventsInput) (req *request.Request, output *PutLogEventsOutput) {
	op := &request.Operation{
		Name:       opPutLogEvents,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutLogEventsInput{}
	}

	req = c.newRequest(op, input, output)
	output = &PutLogEventsOutput{}
	req.Data = output
	return
}

// Uploads a batch of log events to the specified log stream.
//
//  Every PutLogEvents request must include the sequenceToken obtained from
// the response of the previous request. An upload in a newly created log stream
// does not require a sequenceToken.
//
//  The batch of events must satisfy the following constraints:  The maximum
// batch size is 1,048,576 bytes, and this size is calculated as the sum of
// all event messages in UTF-8, plus 26 bytes for each log event. None of the
// log events in the batch can be more than 2 hours in the future. None of the
// log events in the batch can be older than 14 days or the retention period
// of the log group. The log events in the batch must be in chronological ordered
// by their timestamp. The maximum number of log events in a batch is 10,000.
// A batch of log events in a single PutLogEvents request cannot span more than
// 24 hours. Otherwise, the PutLogEvents operation will fail.
func (c *CloudWatchLogs) PutLogEvents(input *PutLogEventsInput) (*PutLogEventsOutput, error) {
	req, out := c.PutLogEventsRequest(input)
	err := req.Send()
	return out, err
}

const opPutMetricFilter = "PutMetricFilter"

// PutMetricFilterRequest generates a request for the PutMetricFilter operation.
func (c *CloudWatchLogs) PutMetricFilterRequest(input *PutMetricFilterInput) (req *request.Request, output *PutMetricFilterOutput) {
	op := &request.Operation{
		Name:       opPutMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutMetricFilterInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &PutMetricFilterOutput{}
	req.Data = output
	return
}

// Creates or updates a metric filter and associates it with the specified log
// group. Metric filters allow you to configure rules to extract metric data
// from log events ingested through PutLogEvents requests.
//
//  The maximum number of metric filters that can be associated with a log
// group is 100.
func (c *CloudWatchLogs) PutMetricFilter(input *PutMetricFilterInput) (*PutMetricFilterOutput, error) {
	req, out := c.PutMetricFilterRequest(input)
	err := req.Send()
	return out, err
}

const opPutRetentionPolicy = "PutRetentionPolicy"

// PutRetentionPolicyRequest generates a request for the PutRetentionPolicy operation.
func (c *CloudWatchLogs) PutRetentionPolicyRequest(input *PutRetentionPolicyInput) (req *request.Request, output *PutRetentionPolicyOutput) {
	op := &request.Operation{
		Name:       opPutRetentionPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutRetentionPolicyInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &PutRetentionPolicyOutput{}
	req.Data = output
	return
}

// Sets the retention of the specified log group. A retention policy allows
// you to configure the number of days you want to retain log events in the
// specified log group.
func (c *CloudWatchLogs) PutRetentionPolicy(input *PutRetentionPolicyInput) (*PutRetentionPolicyOutput, error) {
	req, out := c.PutRetentionPolicyRequest(input)
	err := req.Send()
	return out, err
}

const opPutSubscriptionFilter = "PutSubscriptionFilter"

// PutSubscriptionFilterRequest generates a request for the PutSubscriptionFilter operation.
func (c *CloudWatchLogs) PutSubscriptionFilterRequest(input *PutSubscriptionFilterInput) (req *request.Request, output *PutSubscriptionFilterOutput) {
	op := &request.Operation{
		Name:       opPutSubscriptionFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutSubscriptionFilterInput{}
	}

	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Remove(jsonrpc.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
	output = &PutSubscriptionFilterOutput{}
	req.Data = output
	return
}

// Creates or updates a subscription filter and associates it with the specified
// log group. Subscription filters allow you to subscribe to a real-time stream
// of log events ingested through PutLogEvents requests and have them delivered
// to a specific destination. Currently, the supported destinations are:   An
// Amazon Kinesis stream belonging to the same account as the subscription filter,
// for same-account delivery.   A logical destination (used via an ARN of Destination)
// belonging to a different account, for cross-account delivery.   An Amazon
// Kinesis Firehose stream belonging to the same account as the subscription
// filter, for same-account delivery.   An AWS Lambda function belonging to
// the same account as the subscription filter, for same-account delivery.
//
//
//  Currently there can only be one subscription filter associated with a log
// group.
func (c *CloudWatchLogs) PutSubscriptionFilter(input *PutSubscriptionFilterInput) (*PutSubscriptionFilterOutput, error) {
	req, out := c.PutSubscriptionFilterRequest(input)
	err := req.Send()
	return out, err
}

const opTestMetricFilter = "TestMetricFilter"

// TestMetricFilterRequest generates a request for the TestMetricFilter operation.
func (c *CloudWatchLogs) TestMetricFilterRequest(input *TestMetricFilterInput) (req *request.Request, output *TestMetricFilterOutput) {
	op := &request.Operation{
		Name:       opTestMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &TestMetricFilterInput{}
	}

	req = c.newRequest(op, input, output)
	output = &TestMetricFilterOutput{}
	req.Data = output
	return
}

// Tests the filter pattern of a metric filter against a sample of log event
// messages. You can use this operation to validate the correctness of a metric
// filter pattern.
func (c *CloudWatchLogs) TestMetricFilter(input *TestMetricFilterInput) (*TestMetricFilterOutput, error) {
	req, out := c.TestMetricFilterRequest(input)
	err := req.Send()
	return out, err
}

type CancelExportTaskInput struct {
	_ struct{} `type:"structure"`

	// Id of the export task to cancel.
	TaskId *string `locationName:"taskId" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s CancelExportTaskInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CancelExportTaskInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CancelExportTaskInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CancelExportTaskInput"}
	if s.TaskId == nil {
		invalidParams.Add(request.NewErrParamRequired("TaskId"))
	}
	if s.TaskId != nil && len(*s.TaskId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TaskId", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type CancelExportTaskOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CancelExportTaskOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CancelExportTaskOutput) GoString() string {
	return s.String()
}

type CreateExportTaskInput struct {
	_ struct{} `type:"structure"`

	// Name of Amazon S3 bucket to which the log data will be exported.
	//
	// Note: Only buckets in the same AWS region are supported.
	Destination *string `locationName:"destination" min:"1" type:"string" required:"true"`

	// Prefix that will be used as the start of Amazon S3 key for every object exported.
	// If not specified, this defaults to 'exportedlogs'.
	DestinationPrefix *string `locationName:"destinationPrefix" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. It indicates the start time of the range for the request. Events
	// with a timestamp prior to this time will not be exported.
	From *int64 `locationName:"from" type:"long" required:"true"`

	// The name of the log group to export.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// Will only export log streams that match the provided logStreamNamePrefix.
	// If you don't specify a value, no prefix filter is applied.
	LogStreamNamePrefix *string `locationName:"logStreamNamePrefix" min:"1" type:"string"`

	// The name of the export task.
	TaskName *string `locationName:"taskName" min:"1" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. It indicates the end time of the range for the request. Events
	// with a timestamp later than this time will not be exported.
	To *int64 `locationName:"to" type:"long" required:"true"`
}

// String returns the string representation
func (s CreateExportTaskInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateExportTaskInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateExportTaskInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateExportTaskInput"}
	if s.Destination == nil {
		invalidParams.Add(request.NewErrParamRequired("Destination"))
	}
	if s.Destination != nil && len(*s.Destination) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Destination", 1))
	}
	if s.From == nil {
		invalidParams.Add(request.NewErrParamRequired("From"))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamNamePrefix != nil && len(*s.LogStreamNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamNamePrefix", 1))
	}
	if s.TaskName != nil && len(*s.TaskName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TaskName", 1))
	}
	if s.To == nil {
		invalidParams.Add(request.NewErrParamRequired("To"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type CreateExportTaskOutput struct {
	_ struct{} `type:"structure"`

	// Id of the export task that got created.
	TaskId *string `locationName:"taskId" min:"1" type:"string"`
}

// String returns the string representation
func (s CreateExportTaskOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateExportTaskOutput) GoString() string {
	return s.String()
}

type CreateLogGroupInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group to create.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s CreateLogGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLogGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLogGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLogGroupInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type CreateLogGroupOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLogGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLogGroupOutput) GoString() string {
	return s.String()
}

type CreateLogStreamInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group under which the log stream is to be created.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream to create.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s CreateLogStreamInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLogStreamInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLogStreamInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLogStreamInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogStreamName"))
	}
	if s.LogStreamName != nil && len(*s.LogStreamName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type CreateLogStreamOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLogStreamOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLogStreamOutput) GoString() string {
	return s.String()
}

type DeleteDestinationInput struct {
	_ struct{} `type:"structure"`

	// The name of destination to delete.
	DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteDestinationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteDestinationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteDestinationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteDestinationInput"}
	if s.DestinationName == nil {
		invalidParams.Add(request.NewErrParamRequired("DestinationName"))
	}
	if s.DestinationName != nil && len(*s.DestinationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DestinationName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteDestinationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteDestinationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteDestinationOutput) GoString() string {
	return s.String()
}

type DeleteLogGroupInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group to delete.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLogGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLogGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLogGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLogGroupInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteLogGroupOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLogGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLogGroupOutput) GoString() string {
	return s.String()
}

type DeleteLogStreamInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group under which the log stream to delete belongs.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream to delete.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLogStreamInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLogStreamInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLogStreamInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLogStreamInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogStreamName"))
	}
	if s.LogStreamName != nil && len(*s.LogStreamName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteLogStreamOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLogStreamOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLogStreamOutput) GoString() string {
	return s.String()
}

type DeleteMetricFilterInput struct {
	_ struct{} `type:"structure"`

	// The name of the metric filter to delete.
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// The name of the log group that is associated with the metric filter to delete.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteMetricFilterInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteMetricFilterInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteMetricFilterInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteMetricFilterInput"}
	if s.FilterName == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterName"))
	}
	if s.FilterName != nil && len(*s.FilterName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterName", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteMetricFilterOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteMetricFilterOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteMetricFilterOutput) GoString() string {
	return s.String()
}

type DeleteRetentionPolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group that is associated with the retention policy to
	// delete.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteRetentionPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRetentionPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteRetentionPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteRetentionPolicyInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteRetentionPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteRetentionPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRetentionPolicyOutput) GoString() string {
	return s.String()
}

type DeleteSubscriptionFilterInput struct {
	_ struct{} `type:"structure"`

	// The name of the subscription filter to delete.
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// The name of the log group that is associated with the subscription filter
	// to delete.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteSubscriptionFilterInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteSubscriptionFilterInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteSubscriptionFilterInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteSubscriptionFilterInput"}
	if s.FilterName == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterName"))
	}
	if s.FilterName != nil && len(*s.FilterName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterName", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DeleteSubscriptionFilterOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteSubscriptionFilterOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteSubscriptionFilterOutput) GoString() string {
	return s.String()
}

type DescribeDestinationsInput struct {
	_ struct{} `type:"structure"`

	// Will only return destinations that match the provided destinationNamePrefix.
	// If you don't specify a value, no prefix is applied.
	DestinationNamePrefix *string `min:"1" type:"string"`

	// The maximum number of results to return.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeDestinationsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeDestinationsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeDestinationsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeDestinationsInput"}
	if s.DestinationNamePrefix != nil && len(*s.DestinationNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DestinationNamePrefix", 1))
	}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeDestinationsOutput struct {
	_ struct{} `type:"structure"`

	Destinations []*Destination `locationName:"destinations" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeDestinationsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeDestinationsOutput) GoString() string {
	return s.String()
}

type DescribeExportTasksInput struct {
	_ struct{} `type:"structure"`

	// The maximum number of items returned in the response. If you don't specify
	// a value, the request would return up to 50 items.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous DescribeExportTasks
	// request.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// All export tasks that matches the specified status code will be returned.
	// This can return zero or more export tasks.
	StatusCode *string `locationName:"statusCode" type:"string" enum:"ExportTaskStatusCode"`

	// Export task that matches the specified task Id will be returned. This can
	// result in zero or one export task.
	TaskId *string `locationName:"taskId" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeExportTasksInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeExportTasksInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeExportTasksInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeExportTasksInput"}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}
	if s.TaskId != nil && len(*s.TaskId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TaskId", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeExportTasksOutput struct {
	_ struct{} `type:"structure"`

	// A list of export tasks.
	ExportTasks []*ExportTask `locationName:"exportTasks" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeExportTasksOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeExportTasksOutput) GoString() string {
	return s.String()
}

type DescribeLogGroupsInput struct {
	_ struct{} `type:"structure"`

	// The maximum number of items returned in the response. If you don't specify
	// a value, the request would return up to 50 items.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// Will only return log groups that match the provided logGroupNamePrefix. If
	// you don't specify a value, no prefix filter is applied.
	LogGroupNamePrefix *string `locationName:"logGroupNamePrefix" min:"1" type:"string"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous DescribeLogGroups
	// request.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeLogGroupsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLogGroupsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLogGroupsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLogGroupsInput"}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupNamePrefix != nil && len(*s.LogGroupNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupNamePrefix", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeLogGroupsOutput struct {
	_ struct{} `type:"structure"`

	// A list of log groups.
	LogGroups []*LogGroup `locationName:"logGroups" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeLogGroupsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLogGroupsOutput) GoString() string {
	return s.String()
}

type DescribeLogStreamsInput struct {
	_ struct{} `type:"structure"`

	// If set to true, results are returned in descending order. If you don't specify
	// a value or set it to false, results are returned in ascending order.
	Descending *bool `locationName:"descending" type:"boolean"`

	// The maximum number of items returned in the response. If you don't specify
	// a value, the request would return up to 50 items.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The log group name for which log streams are to be listed.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// Will only return log streams that match the provided logStreamNamePrefix.
	// If you don't specify a value, no prefix filter is applied.
	LogStreamNamePrefix *string `locationName:"logStreamNamePrefix" min:"1" type:"string"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous DescribeLogStreams
	// request.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// Specifies what to order the returned log streams by. Valid arguments are
	// 'LogStreamName' or 'LastEventTime'. If you don't specify a value, results
	// are ordered by LogStreamName. If 'LastEventTime' is chosen, the request cannot
	// also contain a logStreamNamePrefix.
	OrderBy *string `locationName:"orderBy" type:"string" enum:"OrderBy"`
}

// String returns the string representation
func (s DescribeLogStreamsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLogStreamsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLogStreamsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLogStreamsInput"}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamNamePrefix != nil && len(*s.LogStreamNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamNamePrefix", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeLogStreamsOutput struct {
	_ struct{} `type:"structure"`

	// A list of log streams.
	LogStreams []*LogStream `locationName:"logStreams" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeLogStreamsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLogStreamsOutput) GoString() string {
	return s.String()
}

type DescribeMetricFiltersInput struct {
	_ struct{} `type:"structure"`

	// Will only return metric filters that match the provided filterNamePrefix.
	// If you don't specify a value, no prefix filter is applied.
	FilterNamePrefix *string `locationName:"filterNamePrefix" min:"1" type:"string"`

	// The maximum number of items returned in the response. If you don't specify
	// a value, the request would return up to 50 items.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The log group name for which metric filters are to be listed.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous DescribeMetricFilters
	// request.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeMetricFiltersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeMetricFiltersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeMetricFiltersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeMetricFiltersInput"}
	if s.FilterNamePrefix != nil && len(*s.FilterNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterNamePrefix", 1))
	}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeMetricFiltersOutput struct {
	_ struct{} `type:"structure"`

	MetricFilters []*MetricFilter `locationName:"metricFilters" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeMetricFiltersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeMetricFiltersOutput) GoString() string {
	return s.String()
}

type DescribeSubscriptionFiltersInput struct {
	_ struct{} `type:"structure"`

	// Will only return subscription filters that match the provided filterNamePrefix.
	// If you don't specify a value, no prefix filter is applied.
	FilterNamePrefix *string `locationName:"filterNamePrefix" min:"1" type:"string"`

	// The maximum number of results to return.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The log group name for which subscription filters are to be listed.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

// String returns the string representation
func (s DescribeSubscriptionFiltersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeSubscriptionFiltersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeSubscriptionFiltersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeSubscriptionFiltersInput"}
	if s.FilterNamePrefix != nil && len(*s.FilterNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterNamePrefix", 1))
	}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type DescribeSubscriptionFiltersOutput struct {
	_ struct{} `type:"structure"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	SubscriptionFilters []*SubscriptionFilter `locationName:"subscriptionFilters" type:"list"`
}

// String returns the string representation
func (s DescribeSubscriptionFiltersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeSubscriptionFiltersOutput) GoString() string {
	return s.String()
}

// A cross account destination that is the recipient of subscription log events.
type Destination struct {
	_ struct{} `type:"structure"`

	// An IAM policy document that governs which AWS accounts can create subscription
	// filters against this destination.
	AccessPolicy *string `locationName:"accessPolicy" min:"1" type:"string"`

	// ARN of this destination.
	Arn *string `locationName:"arn" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC specifying when this destination was created.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// Name of the destination.
	DestinationName *string `locationName:"destinationName" min:"1" type:"string"`

	// A role for impersonation for delivering log events to the target.
	RoleArn *string `locationName:"roleArn" min:"1" type:"string"`

	// ARN of the physical target where the log events will be delivered (eg. ARN
	// of a Kinesis stream).
	TargetArn *string `locationName:"targetArn" min:"1" type:"string"`
}

// String returns the string representation
func (s Destination) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Destination) GoString() string {
	return s.String()
}

// Represents an export task.
type ExportTask struct {
	_ struct{} `type:"structure"`

	// Name of Amazon S3 bucket to which the log data was exported.
	Destination *string `locationName:"destination" min:"1" type:"string"`

	// Prefix that was used as the start of Amazon S3 key for every object exported.
	DestinationPrefix *string `locationName:"destinationPrefix" type:"string"`

	// Execution info about the export task.
	ExecutionInfo *ExportTaskExecutionInfo `locationName:"executionInfo" type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. Events with a timestamp prior to this time are not exported.
	From *int64 `locationName:"from" type:"long"`

	// The name of the log group from which logs data was exported.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	// Status of the export task.
	Status *ExportTaskStatus `locationName:"status" type:"structure"`

	// Id of the export task.
	TaskId *string `locationName:"taskId" min:"1" type:"string"`

	// The name of the export task.
	TaskName *string `locationName:"taskName" min:"1" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. Events with a timestamp later than this time are not exported.
	To *int64 `locationName:"to" type:"long"`
}

// String returns the string representation
func (s ExportTask) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExportTask) GoString() string {
	return s.String()
}

// Represents the status of an export task.
type ExportTaskExecutionInfo struct {
	_ struct{} `type:"structure"`

	// A point in time when the export task got completed.
	CompletionTime *int64 `locationName:"completionTime" type:"long"`

	// A point in time when the export task got created.
	CreationTime *int64 `locationName:"creationTime" type:"long"`
}

// String returns the string representation
func (s ExportTaskExecutionInfo) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExportTaskExecutionInfo) GoString() string {
	return s.String()
}

// Represents the status of an export task.
type ExportTaskStatus struct {
	_ struct{} `type:"structure"`

	// Status code of the export task.
	Code *string `locationName:"code" type:"string" enum:"ExportTaskStatusCode"`

	// Status message related to the code.
	Message *string `locationName:"message" type:"string"`
}

// String returns the string representation
func (s ExportTaskStatus) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExportTaskStatus) GoString() string {
	return s.String()
}

type FilterLogEventsInput struct {
	_ struct{} `type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. If provided, events with a timestamp later than this time are
	// not returned.
	EndTime *int64 `locationName:"endTime" type:"long"`

	// A valid CloudWatch Logs filter pattern to use for filtering the response.
	// If not provided, all the events are matched.
	FilterPattern *string `locationName:"filterPattern" type:"string"`

	// If provided, the API will make a best effort to provide responses that contain
	// events from multiple log streams within the log group interleaved in a single
	// response. If not provided, all the matched log events in the first log stream
	// will be searched first, then those in the next log stream, etc.
	Interleaved *bool `locationName:"interleaved" type:"boolean"`

	// The maximum number of events to return in a page of results. Default is 10,000
	// events.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The name of the log group to query.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// Optional list of log stream names within the specified log group to search.
	// Defaults to all the log streams in the log group.
	LogStreamNames []*string `locationName:"logStreamNames" min:"1" type:"list"`

	// A pagination token obtained from a FilterLogEvents response to continue paginating
	// the FilterLogEvents results. This token is omitted from the response when
	// there are no other events to display.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC. If provided, events with a timestamp prior to this time are
	// not returned.
	StartTime *int64 `locationName:"startTime" type:"long"`
}

// String returns the string representation
func (s FilterLogEventsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s FilterLogEventsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *FilterLogEventsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "FilterLogEventsInput"}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamNames != nil && len(s.LogStreamNames) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamNames", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type FilterLogEventsOutput struct {
	_ struct{} `type:"structure"`

	// A list of FilteredLogEvent objects representing the matched events from the
	// request.
	Events []*FilteredLogEvent `locationName:"events" type:"list"`

	// A pagination token obtained from a FilterLogEvents response to continue paginating
	// the FilterLogEvents results. This token is omitted from the response when
	// there are no other events to display.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// A list of SearchedLogStream objects indicating which log streams have been
	// searched in this request and whether each has been searched completely or
	// still has more to be paginated.
	SearchedLogStreams []*SearchedLogStream `locationName:"searchedLogStreams" type:"list"`
}

// String returns the string representation
func (s FilterLogEventsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s FilterLogEventsOutput) GoString() string {
	return s.String()
}

// Represents a matched event from a FilterLogEvents request.
type FilteredLogEvent struct {
	_ struct{} `type:"structure"`

	// A unique identifier for this event.
	EventId *string `locationName:"eventId" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	IngestionTime *int64 `locationName:"ingestionTime" type:"long"`

	// The name of the log stream this event belongs to.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string"`

	// The data contained in the log event.
	Message *string `locationName:"message" min:"1" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	Timestamp *int64 `locationName:"timestamp" type:"long"`
}

// String returns the string representation
func (s FilteredLogEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s FilteredLogEvent) GoString() string {
	return s.String()
}

type GetLogEventsInput struct {
	_ struct{} `type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	EndTime *int64 `locationName:"endTime" type:"long"`

	// The maximum number of log events returned in the response. If you don't specify
	// a value, the request would return as many log events as can fit in a response
	// size of 1MB, up to 10,000 log events.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The name of the log group to query.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream to query.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the nextForwardToken or nextBackwardToken
	// fields in the response of the previous GetLogEvents request.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// If set to true, the earliest log events would be returned first. The default
	// is false (the latest log events are returned first).
	StartFromHead *bool `locationName:"startFromHead" type:"boolean"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	StartTime *int64 `locationName:"startTime" type:"long"`
}

// String returns the string representation
func (s GetLogEventsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLogEventsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetLogEventsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetLogEventsInput"}
	if s.Limit != nil && *s.Limit < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Limit", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogStreamName"))
	}
	if s.LogStreamName != nil && len(*s.LogStreamName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamName", 1))
	}
	if s.NextToken != nil && len(*s.NextToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NextToken", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type GetLogEventsOutput struct {
	_ struct{} `type:"structure"`

	Events []*OutputLogEvent `locationName:"events" type:"list"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextBackwardToken *string `locationName:"nextBackwardToken" min:"1" type:"string"`

	// A string token used for pagination that points to the next page of results.
	// It must be a value obtained from the response of the previous request. The
	// token expires after 24 hours.
	NextForwardToken *string `locationName:"nextForwardToken" min:"1" type:"string"`
}

// String returns the string representation
func (s GetLogEventsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLogEventsOutput) GoString() string {
	return s.String()
}

// A log event is a record of some activity that was recorded by the application
// or resource being monitored. The log event record that CloudWatch Logs understands
// contains two properties: the timestamp of when the event occurred, and the
// raw event message.
type InputLogEvent struct {
	_ struct{} `type:"structure"`

	Message *string `locationName:"message" min:"1" type:"string" required:"true"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	Timestamp *int64 `locationName:"timestamp" type:"long" required:"true"`
}

// String returns the string representation
func (s InputLogEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InputLogEvent) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *InputLogEvent) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "InputLogEvent"}
	if s.Message == nil {
		invalidParams.Add(request.NewErrParamRequired("Message"))
	}
	if s.Message != nil && len(*s.Message) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Message", 1))
	}
	if s.Timestamp == nil {
		invalidParams.Add(request.NewErrParamRequired("Timestamp"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type LogGroup struct {
	_ struct{} `type:"structure"`

	Arn *string `locationName:"arn" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	// The number of metric filters associated with the log group.
	MetricFilterCount *int64 `locationName:"metricFilterCount" type:"integer"`

	// Specifies the number of days you want to retain log events in the specified
	// log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180,
	// 365, 400, 545, 731, 1827, 3653.
	RetentionInDays *int64 `locationName:"retentionInDays" type:"integer"`

	StoredBytes *int64 `locationName:"storedBytes" type:"long"`
}

// String returns the string representation
func (s LogGroup) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LogGroup) GoString() string {
	return s.String()
}

// A log stream is sequence of log events from a single emitter of logs.
type LogStream struct {
	_ struct{} `type:"structure"`

	Arn *string `locationName:"arn" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	FirstEventTimestamp *int64 `locationName:"firstEventTimestamp" type:"long"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	LastEventTimestamp *int64 `locationName:"lastEventTimestamp" type:"long"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	LastIngestionTime *int64 `locationName:"lastIngestionTime" type:"long"`

	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string"`

	StoredBytes *int64 `locationName:"storedBytes" type:"long"`

	// A string token used for making PutLogEvents requests. A sequenceToken can
	// only be used once, and PutLogEvents requests must include the sequenceToken
	// obtained from the response of the previous request.
	UploadSequenceToken *string `locationName:"uploadSequenceToken" min:"1" type:"string"`
}

// String returns the string representation
func (s LogStream) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LogStream) GoString() string {
	return s.String()
}

// Metric filters can be used to express how CloudWatch Logs would extract metric
// observations from ingested log events and transform them to metric data in
// a CloudWatch metric.
type MetricFilter struct {
	_ struct{} `type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// A name for a metric or subscription filter.
	FilterName *string `locationName:"filterName" min:"1" type:"string"`

	// A symbolic description of how CloudWatch Logs should interpret the data in
	// each log event. For example, a log event may contain timestamps, IP addresses,
	// strings, and so on. You use the filter pattern to specify what to look for
	// in the log event message.
	FilterPattern *string `locationName:"filterPattern" type:"string"`

	MetricTransformations []*MetricTransformation `locationName:"metricTransformations" min:"1" type:"list"`
}

// String returns the string representation
func (s MetricFilter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricFilter) GoString() string {
	return s.String()
}

type MetricFilterMatchRecord struct {
	_ struct{} `type:"structure"`

	EventMessage *string `locationName:"eventMessage" min:"1" type:"string"`

	EventNumber *int64 `locationName:"eventNumber" type:"long"`

	ExtractedValues map[string]*string `locationName:"extractedValues" type:"map"`
}

// String returns the string representation
func (s MetricFilterMatchRecord) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricFilterMatchRecord) GoString() string {
	return s.String()
}

type MetricTransformation struct {
	_ struct{} `type:"structure"`

	// The name of the CloudWatch metric to which the monitored log information
	// should be published. For example, you may publish to a metric called ErrorCount.
	MetricName *string `locationName:"metricName" type:"string" required:"true"`

	// The destination namespace of the new CloudWatch metric.
	MetricNamespace *string `locationName:"metricNamespace" type:"string" required:"true"`

	// What to publish to the metric. For example, if you're counting the occurrences
	// of a particular term like "Error", the value will be "1" for each occurrence.
	// If you're counting the bytes transferred the published value will be the
	// value in the log event.
	MetricValue *string `locationName:"metricValue" type:"string" required:"true"`
}

// String returns the string representation
func (s MetricTransformation) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricTransformation) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *MetricTransformation) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "MetricTransformation"}
	if s.MetricName == nil {
		invalidParams.Add(request.NewErrParamRequired("MetricName"))
	}
	if s.MetricNamespace == nil {
		invalidParams.Add(request.NewErrParamRequired("MetricNamespace"))
	}
	if s.MetricValue == nil {
		invalidParams.Add(request.NewErrParamRequired("MetricValue"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type OutputLogEvent struct {
	_ struct{} `type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	IngestionTime *int64 `locationName:"ingestionTime" type:"long"`

	Message *string `locationName:"message" min:"1" type:"string"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	Timestamp *int64 `locationName:"timestamp" type:"long"`
}

// String returns the string representation
func (s OutputLogEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s OutputLogEvent) GoString() string {
	return s.String()
}

type PutDestinationInput struct {
	_ struct{} `type:"structure"`

	// A name for the destination.
	DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"`

	// The ARN of an IAM role that grants CloudWatch Logs permissions to do Amazon
	// Kinesis PutRecord requests on the desitnation stream.
	RoleArn *string `locationName:"roleArn" min:"1" type:"string" required:"true"`

	// The ARN of an Amazon Kinesis stream to deliver matching log events to.
	TargetArn *string `locationName:"targetArn" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s PutDestinationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutDestinationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutDestinationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutDestinationInput"}
	if s.DestinationName == nil {
		invalidParams.Add(request.NewErrParamRequired("DestinationName"))
	}
	if s.DestinationName != nil && len(*s.DestinationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DestinationName", 1))
	}
	if s.RoleArn == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
	}
	if s.RoleArn != nil && len(*s.RoleArn) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 1))
	}
	if s.TargetArn == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetArn"))
	}
	if s.TargetArn != nil && len(*s.TargetArn) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TargetArn", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutDestinationOutput struct {
	_ struct{} `type:"structure"`

	// A cross account destination that is the recipient of subscription log events.
	Destination *Destination `locationName:"destination" type:"structure"`
}

// String returns the string representation
func (s PutDestinationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutDestinationOutput) GoString() string {
	return s.String()
}

type PutDestinationPolicyInput struct {
	_ struct{} `type:"structure"`

	// An IAM policy document that authorizes cross-account users to deliver their
	// log events to associated destination.
	AccessPolicy *string `locationName:"accessPolicy" min:"1" type:"string" required:"true"`

	// A name for an existing destination.
	DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s PutDestinationPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutDestinationPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutDestinationPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutDestinationPolicyInput"}
	if s.AccessPolicy == nil {
		invalidParams.Add(request.NewErrParamRequired("AccessPolicy"))
	}
	if s.AccessPolicy != nil && len(*s.AccessPolicy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AccessPolicy", 1))
	}
	if s.DestinationName == nil {
		invalidParams.Add(request.NewErrParamRequired("DestinationName"))
	}
	if s.DestinationName != nil && len(*s.DestinationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DestinationName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutDestinationPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutDestinationPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutDestinationPolicyOutput) GoString() string {
	return s.String()
}

type PutLogEventsInput struct {
	_ struct{} `type:"structure"`

	// A list of log events belonging to a log stream.
	LogEvents []*InputLogEvent `locationName:"logEvents" min:"1" type:"list" required:"true"`

	// The name of the log group to put log events to.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream to put log events to.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"`

	// A string token that must be obtained from the response of the previous PutLogEvents
	// request.
	SequenceToken *string `locationName:"sequenceToken" min:"1" type:"string"`
}

// String returns the string representation
func (s PutLogEventsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLogEventsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutLogEventsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutLogEventsInput"}
	if s.LogEvents == nil {
		invalidParams.Add(request.NewErrParamRequired("LogEvents"))
	}
	if s.LogEvents != nil && len(s.LogEvents) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogEvents", 1))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.LogStreamName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogStreamName"))
	}
	if s.LogStreamName != nil && len(*s.LogStreamName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamName", 1))
	}
	if s.SequenceToken != nil && len(*s.SequenceToken) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("SequenceToken", 1))
	}
	if s.LogEvents != nil {
		for i, v := range s.LogEvents {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LogEvents", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutLogEventsOutput struct {
	_ struct{} `type:"structure"`

	// A string token used for making PutLogEvents requests. A sequenceToken can
	// only be used once, and PutLogEvents requests must include the sequenceToken
	// obtained from the response of the previous request.
	NextSequenceToken *string `locationName:"nextSequenceToken" min:"1" type:"string"`

	RejectedLogEventsInfo *RejectedLogEventsInfo `locationName:"rejectedLogEventsInfo" type:"structure"`
}

// String returns the string representation
func (s PutLogEventsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLogEventsOutput) GoString() string {
	return s.String()
}

type PutMetricFilterInput struct {
	_ struct{} `type:"structure"`

	// A name for the metric filter.
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// A valid CloudWatch Logs filter pattern for extracting metric data out of
	// ingested log events.
	FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"`

	// The name of the log group to associate the metric filter with.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// A collection of information needed to define how metric data gets emitted.
	MetricTransformations []*MetricTransformation `locationName:"metricTransformations" min:"1" type:"list" required:"true"`
}

// String returns the string representation
func (s PutMetricFilterInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutMetricFilterInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutMetricFilterInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutMetricFilterInput"}
	if s.FilterName == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterName"))
	}
	if s.FilterName != nil && len(*s.FilterName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterName", 1))
	}
	if s.FilterPattern == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterPattern"))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.MetricTransformations == nil {
		invalidParams.Add(request.NewErrParamRequired("MetricTransformations"))
	}
	if s.MetricTransformations != nil && len(s.MetricTransformations) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("MetricTransformations", 1))
	}
	if s.MetricTransformations != nil {
		for i, v := range s.MetricTransformations {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "MetricTransformations", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutMetricFilterOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutMetricFilterOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutMetricFilterOutput) GoString() string {
	return s.String()
}

type PutRetentionPolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the log group to associate the retention policy with.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// Specifies the number of days you want to retain log events in the specified
	// log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180,
	// 365, 400, 545, 731, 1827, 3653.
	RetentionInDays *int64 `locationName:"retentionInDays" type:"integer" required:"true"`
}

// String returns the string representation
func (s PutRetentionPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutRetentionPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutRetentionPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutRetentionPolicyInput"}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.RetentionInDays == nil {
		invalidParams.Add(request.NewErrParamRequired("RetentionInDays"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutRetentionPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutRetentionPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutRetentionPolicyOutput) GoString() string {
	return s.String()
}

type PutSubscriptionFilterInput struct {
	_ struct{} `type:"structure"`

	// The ARN of the destination to deliver matching log events to. Currently,
	// the supported destinations are:   An Amazon Kinesis stream belonging to the
	// same account as the subscription filter, for same-account delivery.   A logical
	// destination (used via an ARN of Destination) belonging to a different account,
	// for cross-account delivery.   An Amazon Kinesis Firehose stream belonging
	// to the same account as the subscription filter, for same-account delivery.
	//   An AWS Lambda function belonging to the same account as the subscription
	// filter, for same-account delivery.
	DestinationArn *string `locationName:"destinationArn" min:"1" type:"string" required:"true"`

	// A name for the subscription filter.
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// A valid CloudWatch Logs filter pattern for subscribing to a filtered stream
	// of log events.
	FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"`

	// The name of the log group to associate the subscription filter with.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The ARN of an IAM role that grants CloudWatch Logs permissions to deliver
	// ingested log events to the destination stream. You don't need to provide
	// the ARN when you are working with a logical destination (used via an ARN
	// of Destination) for cross-account delivery.
	RoleArn *string `locationName:"roleArn" min:"1" type:"string"`
}

// String returns the string representation
func (s PutSubscriptionFilterInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutSubscriptionFilterInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutSubscriptionFilterInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutSubscriptionFilterInput"}
	if s.DestinationArn == nil {
		invalidParams.Add(request.NewErrParamRequired("DestinationArn"))
	}
	if s.DestinationArn != nil && len(*s.DestinationArn) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DestinationArn", 1))
	}
	if s.FilterName == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterName"))
	}
	if s.FilterName != nil && len(*s.FilterName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("FilterName", 1))
	}
	if s.FilterPattern == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterPattern"))
	}
	if s.LogGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("LogGroupName"))
	}
	if s.LogGroupName != nil && len(*s.LogGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogGroupName", 1))
	}
	if s.RoleArn != nil && len(*s.RoleArn) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type PutSubscriptionFilterOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutSubscriptionFilterOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutSubscriptionFilterOutput) GoString() string {
	return s.String()
}

type RejectedLogEventsInfo struct {
	_ struct{} `type:"structure"`

	ExpiredLogEventEndIndex *int64 `locationName:"expiredLogEventEndIndex" type:"integer"`

	TooNewLogEventStartIndex *int64 `locationName:"tooNewLogEventStartIndex" type:"integer"`

	TooOldLogEventEndIndex *int64 `locationName:"tooOldLogEventEndIndex" type:"integer"`
}

// String returns the string representation
func (s RejectedLogEventsInfo) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RejectedLogEventsInfo) GoString() string {
	return s.String()
}

// An object indicating the search status of a log stream in a FilterLogEvents
// request.
type SearchedLogStream struct {
	_ struct{} `type:"structure"`

	// The name of the log stream.
	LogStreamName *string `locationName:"logStreamName" min:"1" type:"string"`

	// Indicates whether all the events in this log stream were searched or more
	// data exists to search by paginating further.
	SearchedCompletely *bool `locationName:"searchedCompletely" type:"boolean"`
}

// String returns the string representation
func (s SearchedLogStream) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SearchedLogStream) GoString() string {
	return s.String()
}

type SubscriptionFilter struct {
	_ struct{} `type:"structure"`

	// A point in time expressed as the number of milliseconds since Jan 1, 1970
	// 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	DestinationArn *string `locationName:"destinationArn" min:"1" type:"string"`

	// A name for a metric or subscription filter.
	FilterName *string `locationName:"filterName" min:"1" type:"string"`

	// A symbolic description of how CloudWatch Logs should interpret the data in
	// each log event. For example, a log event may contain timestamps, IP addresses,
	// strings, and so on. You use the filter pattern to specify what to look for
	// in the log event message.
	FilterPattern *string `locationName:"filterPattern" type:"string"`

	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	RoleArn *string `locationName:"roleArn" min:"1" type:"string"`
}

// String returns the string representation
func (s SubscriptionFilter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SubscriptionFilter) GoString() string {
	return s.String()
}

type TestMetricFilterInput struct {
	_ struct{} `type:"structure"`

	// A symbolic description of how CloudWatch Logs should interpret the data in
	// each log event. For example, a log event may contain timestamps, IP addresses,
	// strings, and so on. You use the filter pattern to specify what to look for
	// in the log event message.
	FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"`

	// A list of log event messages to test.
	LogEventMessages []*string `locationName:"logEventMessages" min:"1" type:"list" required:"true"`
}

// String returns the string representation
func (s TestMetricFilterInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TestMetricFilterInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *TestMetricFilterInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TestMetricFilterInput"}
	if s.FilterPattern == nil {
		invalidParams.Add(request.NewErrParamRequired("FilterPattern"))
	}
	if s.LogEventMessages == nil {
		invalidParams.Add(request.NewErrParamRequired("LogEventMessages"))
	}
	if s.LogEventMessages != nil && len(s.LogEventMessages) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogEventMessages", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

type TestMetricFilterOutput struct {
	_ struct{} `type:"structure"`

	Matches []*MetricFilterMatchRecord `locationName:"matches" type:"list"`
}

// String returns the string representation
func (s TestMetricFilterOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TestMetricFilterOutput) GoString() string {
	return s.String()
}

const (
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodeCancelled = "CANCELLED"
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodeCompleted = "COMPLETED"
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodeFailed = "FAILED"
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodePending = "PENDING"
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodePendingCancel = "PENDING_CANCEL"
	// @enum ExportTaskStatusCode
	ExportTaskStatusCodeRunning = "RUNNING"
)

const (
	// @enum OrderBy
	OrderByLogStreamName = "LogStreamName"
	// @enum OrderBy
	OrderByLastEventTime = "LastEventTime"
)
