// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package cloudwatchlogs

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"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 opAssociateKmsKey = "AssociateKmsKey"

// AssociateKmsKeyRequest generates a "aws/request.Request" representing the
// client's request for the AssociateKmsKey operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AssociateKmsKey for more information on using the AssociateKmsKey
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AssociateKmsKeyRequest method.
//    req, resp := client.AssociateKmsKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/AssociateKmsKey
func (c *CloudWatchLogs) AssociateKmsKeyRequest(input *AssociateKmsKeyInput) (req *request.Request, output *AssociateKmsKeyOutput) {
	op := &request.Operation{
		Name:       opAssociateKmsKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AssociateKmsKeyInput{}
	}

	output = &AssociateKmsKeyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// AssociateKmsKey API operation for Amazon CloudWatch Logs.
//
// Associates the specified AWS Key Management Service (AWS KMS) customer master
// key (CMK) with the specified log group.
//
// Associating an AWS KMS CMK with a log group overrides any existing associations
// between the log group and a CMK. After a CMK is associated with a log group,
// all newly ingested data for the log group is encrypted using the CMK. This
// association is stored as long as the data encrypted with the CMK is still
// within Amazon CloudWatch Logs. This enables Amazon CloudWatch Logs to decrypt
// this data whenever it is requested.
//
// Important: CloudWatch Logs supports only symmetric CMKs. Do not use an associate
// an asymmetric CMK with your log group. For more information, see Using Symmetric
// and Asymmetric Keys (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html).
//
// Note that it can take up to 5 minutes for this operation to take effect.
//
// If you attempt to associate a CMK with a log group but the CMK does not exist
// or the CMK is disabled, you will receive an InvalidParameterException error.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation AssociateKmsKey for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/AssociateKmsKey
func (c *CloudWatchLogs) AssociateKmsKey(input *AssociateKmsKeyInput) (*AssociateKmsKeyOutput, error) {
	req, out := c.AssociateKmsKeyRequest(input)
	return out, req.Send()
}

// AssociateKmsKeyWithContext is the same as AssociateKmsKey with the addition of
// the ability to pass a context and additional request options.
//
// See AssociateKmsKey for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) AssociateKmsKeyWithContext(ctx aws.Context, input *AssociateKmsKeyInput, opts ...request.Option) (*AssociateKmsKeyOutput, error) {
	req, out := c.AssociateKmsKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCancelExportTask = "CancelExportTask"

// CancelExportTaskRequest generates a "aws/request.Request" representing the
// client's request for the CancelExportTask operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CancelExportTask for more information on using the CancelExportTask
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CancelExportTaskRequest method.
//    req, resp := client.CancelExportTaskRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CancelExportTask
func (c *CloudWatchLogs) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) {
	op := &request.Operation{
		Name:       opCancelExportTask,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// CancelExportTask API operation for Amazon CloudWatch Logs.
//
// Cancels the specified export task.
//
// The task must be in the PENDING or RUNNING state.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation CancelExportTask for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * InvalidOperationException
//   The operation is not valid on the specified resource.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CancelExportTask
func (c *CloudWatchLogs) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskOutput, error) {
	req, out := c.CancelExportTaskRequest(input)
	return out, req.Send()
}

// CancelExportTaskWithContext is the same as CancelExportTask with the addition of
// the ability to pass a context and additional request options.
//
// See CancelExportTask for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) CancelExportTaskWithContext(ctx aws.Context, input *CancelExportTaskInput, opts ...request.Option) (*CancelExportTaskOutput, error) {
	req, out := c.CancelExportTaskRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateExportTask = "CreateExportTask"

// CreateExportTaskRequest generates a "aws/request.Request" representing the
// client's request for the CreateExportTask operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateExportTask for more information on using the CreateExportTask
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateExportTaskRequest method.
//    req, resp := client.CreateExportTaskRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateExportTask
func (c *CloudWatchLogs) CreateExportTaskRequest(input *CreateExportTaskInput) (req *request.Request, output *CreateExportTaskOutput) {
	op := &request.Operation{
		Name:       opCreateExportTask,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// CreateExportTask API operation for Amazon CloudWatch Logs.
//
// Creates an export task, which allows you to efficiently export data from
// a log group to an Amazon S3 bucket.
//
// This is an asynchronous call. If all the required information is provided,
// this operation initiates an export task and responds with the ID of the task.
// After the task has started, you can use DescribeExportTasks to get the status
// of the export task. Each account can only have one active (RUNNING or PENDING)
// export task at a time. To cancel an export task, use CancelExportTask.
//
// You can export logs from multiple log groups or multiple time ranges to the
// same S3 bucket. To separate out log data for each export task, you can specify
// a prefix to be used as the Amazon S3 key prefix for all exported objects.
//
// Exporting to S3 buckets that are encrypted with AES-256 is supported. Exporting
// to S3 buckets encrypted with SSE-KMS is not supported.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation CreateExportTask for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ResourceAlreadyExistsException
//   The specified resource already exists.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateExportTask
func (c *CloudWatchLogs) CreateExportTask(input *CreateExportTaskInput) (*CreateExportTaskOutput, error) {
	req, out := c.CreateExportTaskRequest(input)
	return out, req.Send()
}

// CreateExportTaskWithContext is the same as CreateExportTask with the addition of
// the ability to pass a context and additional request options.
//
// See CreateExportTask for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) CreateExportTaskWithContext(ctx aws.Context, input *CreateExportTaskInput, opts ...request.Option) (*CreateExportTaskOutput, error) {
	req, out := c.CreateExportTaskRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLogGroup = "CreateLogGroup"

// CreateLogGroupRequest generates a "aws/request.Request" representing the
// client's request for the CreateLogGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLogGroup for more information on using the CreateLogGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLogGroupRequest method.
//    req, resp := client.CreateLogGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateLogGroup
func (c *CloudWatchLogs) CreateLogGroupRequest(input *CreateLogGroupInput) (req *request.Request, output *CreateLogGroupOutput) {
	op := &request.Operation{
		Name:       opCreateLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// CreateLogGroup API operation for Amazon CloudWatch Logs.
//
// Creates a log group with the specified name.
//
// You can create up to 20,000 log groups per account.
//
// You must use the following guidelines when naming a log group:
//
//    * Log group names must be unique within a region for an AWS account.
//
//    * Log group names can be between 1 and 512 characters long.
//
//    * Log group names consist of the following characters: a-z, A-Z, 0-9,
//    '_' (underscore), '-' (hyphen), '/' (forward slash), '.' (period), and
//    '#' (number sign)
//
// If you associate a AWS Key Management Service (AWS KMS) customer master key
// (CMK) with the log group, ingested data is encrypted using the CMK. This
// association is stored as long as the data encrypted with the CMK is still
// within Amazon CloudWatch Logs. This enables Amazon CloudWatch Logs to decrypt
// this data whenever it is requested.
//
// If you attempt to associate a CMK with the log group but the CMK does not
// exist or the CMK is disabled, you will receive an InvalidParameterException
// error.
//
// Important: CloudWatch Logs supports only symmetric CMKs. Do not associate
// an asymmetric CMK with your log group. For more information, see Using Symmetric
// and Asymmetric Keys (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html).
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation CreateLogGroup for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceAlreadyExistsException
//   The specified resource already exists.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateLogGroup
func (c *CloudWatchLogs) CreateLogGroup(input *CreateLogGroupInput) (*CreateLogGroupOutput, error) {
	req, out := c.CreateLogGroupRequest(input)
	return out, req.Send()
}

// CreateLogGroupWithContext is the same as CreateLogGroup with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLogGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) CreateLogGroupWithContext(ctx aws.Context, input *CreateLogGroupInput, opts ...request.Option) (*CreateLogGroupOutput, error) {
	req, out := c.CreateLogGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLogStream = "CreateLogStream"

// CreateLogStreamRequest generates a "aws/request.Request" representing the
// client's request for the CreateLogStream operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLogStream for more information on using the CreateLogStream
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLogStreamRequest method.
//    req, resp := client.CreateLogStreamRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateLogStream
func (c *CloudWatchLogs) CreateLogStreamRequest(input *CreateLogStreamInput) (req *request.Request, output *CreateLogStreamOutput) {
	op := &request.Operation{
		Name:       opCreateLogStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// CreateLogStream API operation for Amazon CloudWatch Logs.
//
// Creates a log stream for the specified log group.
//
// There is no limit on the number of log streams that you can create for a
// log group. There is a limit of 50 TPS on CreateLogStream operations, after
// which transactions are throttled.
//
// You must use the following guidelines when naming a log stream:
//
//    * Log stream names must be unique within the log group.
//
//    * Log stream names can be between 1 and 512 characters long.
//
//    * The ':' (colon) and '*' (asterisk) characters are not allowed.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation CreateLogStream for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceAlreadyExistsException
//   The specified resource already exists.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/CreateLogStream
func (c *CloudWatchLogs) CreateLogStream(input *CreateLogStreamInput) (*CreateLogStreamOutput, error) {
	req, out := c.CreateLogStreamRequest(input)
	return out, req.Send()
}

// CreateLogStreamWithContext is the same as CreateLogStream with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLogStream for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) CreateLogStreamWithContext(ctx aws.Context, input *CreateLogStreamInput, opts ...request.Option) (*CreateLogStreamOutput, error) {
	req, out := c.CreateLogStreamRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteDestination = "DeleteDestination"

// DeleteDestinationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteDestination operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteDestination for more information on using the DeleteDestination
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteDestinationRequest method.
//    req, resp := client.DeleteDestinationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteDestination
func (c *CloudWatchLogs) DeleteDestinationRequest(input *DeleteDestinationInput) (req *request.Request, output *DeleteDestinationOutput) {
	op := &request.Operation{
		Name:       opDeleteDestination,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteDestination API operation for Amazon CloudWatch Logs.
//
// Deletes the specified destination, and eventually disables all the subscription
// filters that publish to it. This operation does not delete the physical resource
// encapsulated by the destination.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteDestination for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteDestination
func (c *CloudWatchLogs) DeleteDestination(input *DeleteDestinationInput) (*DeleteDestinationOutput, error) {
	req, out := c.DeleteDestinationRequest(input)
	return out, req.Send()
}

// DeleteDestinationWithContext is the same as DeleteDestination with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteDestination for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteDestinationWithContext(ctx aws.Context, input *DeleteDestinationInput, opts ...request.Option) (*DeleteDestinationOutput, error) {
	req, out := c.DeleteDestinationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLogGroup = "DeleteLogGroup"

// DeleteLogGroupRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLogGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLogGroup for more information on using the DeleteLogGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLogGroupRequest method.
//    req, resp := client.DeleteLogGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteLogGroup
func (c *CloudWatchLogs) DeleteLogGroupRequest(input *DeleteLogGroupInput) (req *request.Request, output *DeleteLogGroupOutput) {
	op := &request.Operation{
		Name:       opDeleteLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteLogGroup API operation for Amazon CloudWatch Logs.
//
// Deletes the specified log group and permanently deletes all the archived
// log events associated with the log group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteLogGroup for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteLogGroup
func (c *CloudWatchLogs) DeleteLogGroup(input *DeleteLogGroupInput) (*DeleteLogGroupOutput, error) {
	req, out := c.DeleteLogGroupRequest(input)
	return out, req.Send()
}

// DeleteLogGroupWithContext is the same as DeleteLogGroup with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLogGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteLogGroupWithContext(ctx aws.Context, input *DeleteLogGroupInput, opts ...request.Option) (*DeleteLogGroupOutput, error) {
	req, out := c.DeleteLogGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLogStream = "DeleteLogStream"

// DeleteLogStreamRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLogStream operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLogStream for more information on using the DeleteLogStream
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLogStreamRequest method.
//    req, resp := client.DeleteLogStreamRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteLogStream
func (c *CloudWatchLogs) DeleteLogStreamRequest(input *DeleteLogStreamInput) (req *request.Request, output *DeleteLogStreamOutput) {
	op := &request.Operation{
		Name:       opDeleteLogStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteLogStream API operation for Amazon CloudWatch Logs.
//
// Deletes the specified log stream and permanently deletes all the archived
// log events associated with the log stream.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteLogStream for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteLogStream
func (c *CloudWatchLogs) DeleteLogStream(input *DeleteLogStreamInput) (*DeleteLogStreamOutput, error) {
	req, out := c.DeleteLogStreamRequest(input)
	return out, req.Send()
}

// DeleteLogStreamWithContext is the same as DeleteLogStream with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLogStream for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteLogStreamWithContext(ctx aws.Context, input *DeleteLogStreamInput, opts ...request.Option) (*DeleteLogStreamOutput, error) {
	req, out := c.DeleteLogStreamRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteMetricFilter = "DeleteMetricFilter"

// DeleteMetricFilterRequest generates a "aws/request.Request" representing the
// client's request for the DeleteMetricFilter operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteMetricFilter for more information on using the DeleteMetricFilter
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteMetricFilterRequest method.
//    req, resp := client.DeleteMetricFilterRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteMetricFilter
func (c *CloudWatchLogs) DeleteMetricFilterRequest(input *DeleteMetricFilterInput) (req *request.Request, output *DeleteMetricFilterOutput) {
	op := &request.Operation{
		Name:       opDeleteMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteMetricFilter API operation for Amazon CloudWatch Logs.
//
// Deletes the specified metric filter.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteMetricFilter for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteMetricFilter
func (c *CloudWatchLogs) DeleteMetricFilter(input *DeleteMetricFilterInput) (*DeleteMetricFilterOutput, error) {
	req, out := c.DeleteMetricFilterRequest(input)
	return out, req.Send()
}

// DeleteMetricFilterWithContext is the same as DeleteMetricFilter with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteMetricFilter for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteMetricFilterWithContext(ctx aws.Context, input *DeleteMetricFilterInput, opts ...request.Option) (*DeleteMetricFilterOutput, error) {
	req, out := c.DeleteMetricFilterRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteResourcePolicy = "DeleteResourcePolicy"

// DeleteResourcePolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteResourcePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteResourcePolicy for more information on using the DeleteResourcePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteResourcePolicyRequest method.
//    req, resp := client.DeleteResourcePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteResourcePolicy
func (c *CloudWatchLogs) DeleteResourcePolicyRequest(input *DeleteResourcePolicyInput) (req *request.Request, output *DeleteResourcePolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteResourcePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteResourcePolicyInput{}
	}

	output = &DeleteResourcePolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteResourcePolicy API operation for Amazon CloudWatch Logs.
//
// Deletes a resource policy from this account. This revokes the access of the
// identities in that policy to put log events to this account.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteResourcePolicy for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteResourcePolicy
func (c *CloudWatchLogs) DeleteResourcePolicy(input *DeleteResourcePolicyInput) (*DeleteResourcePolicyOutput, error) {
	req, out := c.DeleteResourcePolicyRequest(input)
	return out, req.Send()
}

// DeleteResourcePolicyWithContext is the same as DeleteResourcePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteResourcePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteResourcePolicyWithContext(ctx aws.Context, input *DeleteResourcePolicyInput, opts ...request.Option) (*DeleteResourcePolicyOutput, error) {
	req, out := c.DeleteResourcePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteRetentionPolicy = "DeleteRetentionPolicy"

// DeleteRetentionPolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteRetentionPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteRetentionPolicy for more information on using the DeleteRetentionPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteRetentionPolicyRequest method.
//    req, resp := client.DeleteRetentionPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteRetentionPolicy
func (c *CloudWatchLogs) DeleteRetentionPolicyRequest(input *DeleteRetentionPolicyInput) (req *request.Request, output *DeleteRetentionPolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteRetentionPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteRetentionPolicy API operation for Amazon CloudWatch Logs.
//
// Deletes the specified retention policy.
//
// Log events do not expire if they belong to log groups without a retention
// policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteRetentionPolicy for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteRetentionPolicy
func (c *CloudWatchLogs) DeleteRetentionPolicy(input *DeleteRetentionPolicyInput) (*DeleteRetentionPolicyOutput, error) {
	req, out := c.DeleteRetentionPolicyRequest(input)
	return out, req.Send()
}

// DeleteRetentionPolicyWithContext is the same as DeleteRetentionPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteRetentionPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteRetentionPolicyWithContext(ctx aws.Context, input *DeleteRetentionPolicyInput, opts ...request.Option) (*DeleteRetentionPolicyOutput, error) {
	req, out := c.DeleteRetentionPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteSubscriptionFilter = "DeleteSubscriptionFilter"

// DeleteSubscriptionFilterRequest generates a "aws/request.Request" representing the
// client's request for the DeleteSubscriptionFilter operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteSubscriptionFilter for more information on using the DeleteSubscriptionFilter
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteSubscriptionFilterRequest method.
//    req, resp := client.DeleteSubscriptionFilterRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteSubscriptionFilter
func (c *CloudWatchLogs) DeleteSubscriptionFilterRequest(input *DeleteSubscriptionFilterInput) (req *request.Request, output *DeleteSubscriptionFilterOutput) {
	op := &request.Operation{
		Name:       opDeleteSubscriptionFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DeleteSubscriptionFilter API operation for Amazon CloudWatch Logs.
//
// Deletes the specified subscription filter.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DeleteSubscriptionFilter for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteSubscriptionFilter
func (c *CloudWatchLogs) DeleteSubscriptionFilter(input *DeleteSubscriptionFilterInput) (*DeleteSubscriptionFilterOutput, error) {
	req, out := c.DeleteSubscriptionFilterRequest(input)
	return out, req.Send()
}

// DeleteSubscriptionFilterWithContext is the same as DeleteSubscriptionFilter with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteSubscriptionFilter for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DeleteSubscriptionFilterWithContext(ctx aws.Context, input *DeleteSubscriptionFilterInput, opts ...request.Option) (*DeleteSubscriptionFilterOutput, error) {
	req, out := c.DeleteSubscriptionFilterRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeDestinations = "DescribeDestinations"

// DescribeDestinationsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeDestinations operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeDestinations for more information on using the DescribeDestinations
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeDestinationsRequest method.
//    req, resp := client.DescribeDestinationsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeDestinations
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{}
	}

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

// DescribeDestinations API operation for Amazon CloudWatch Logs.
//
// Lists all your destinations. The results are ASCII-sorted by destination
// name.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeDestinations for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeDestinations
func (c *CloudWatchLogs) DescribeDestinations(input *DescribeDestinationsInput) (*DescribeDestinationsOutput, error) {
	req, out := c.DescribeDestinationsRequest(input)
	return out, req.Send()
}

// DescribeDestinationsWithContext is the same as DescribeDestinations with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeDestinations for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeDestinationsWithContext(ctx aws.Context, input *DescribeDestinationsInput, opts ...request.Option) (*DescribeDestinationsOutput, error) {
	req, out := c.DescribeDestinationsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeDestinationsPages iterates over the pages of a DescribeDestinations operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeDestinations method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeDestinations operation.
//    pageNum := 0
//    err := client.DescribeDestinationsPages(params,
//        func(page *cloudwatchlogs.DescribeDestinationsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) DescribeDestinationsPages(input *DescribeDestinationsInput, fn func(*DescribeDestinationsOutput, bool) bool) error {
	return c.DescribeDestinationsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeDestinationsPagesWithContext same as DescribeDestinationsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeDestinationsPagesWithContext(ctx aws.Context, input *DescribeDestinationsInput, fn func(*DescribeDestinationsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeDestinationsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeDestinationsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*DescribeDestinationsOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opDescribeExportTasks = "DescribeExportTasks"

// DescribeExportTasksRequest generates a "aws/request.Request" representing the
// client's request for the DescribeExportTasks operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeExportTasks for more information on using the DescribeExportTasks
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeExportTasksRequest method.
//    req, resp := client.DescribeExportTasksRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeExportTasks
func (c *CloudWatchLogs) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) {
	op := &request.Operation{
		Name:       opDescribeExportTasks,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DescribeExportTasks API operation for Amazon CloudWatch Logs.
//
// Lists the specified export tasks. You can list all your export tasks or filter
// the results based on task ID or task status.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeExportTasks for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeExportTasks
func (c *CloudWatchLogs) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExportTasksOutput, error) {
	req, out := c.DescribeExportTasksRequest(input)
	return out, req.Send()
}

// DescribeExportTasksWithContext is the same as DescribeExportTasks with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeExportTasks for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeExportTasksWithContext(ctx aws.Context, input *DescribeExportTasksInput, opts ...request.Option) (*DescribeExportTasksOutput, error) {
	req, out := c.DescribeExportTasksRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLogGroups = "DescribeLogGroups"

// DescribeLogGroupsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLogGroups operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLogGroups for more information on using the DescribeLogGroups
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLogGroupsRequest method.
//    req, resp := client.DescribeLogGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeLogGroups
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{}
	}

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

// DescribeLogGroups API operation for Amazon CloudWatch Logs.
//
// Lists the specified log groups. You can list all your log groups or filter
// the results by prefix. The results are ASCII-sorted by log group name.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeLogGroups for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeLogGroups
func (c *CloudWatchLogs) DescribeLogGroups(input *DescribeLogGroupsInput) (*DescribeLogGroupsOutput, error) {
	req, out := c.DescribeLogGroupsRequest(input)
	return out, req.Send()
}

// DescribeLogGroupsWithContext is the same as DescribeLogGroups with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLogGroups for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeLogGroupsWithContext(ctx aws.Context, input *DescribeLogGroupsInput, opts ...request.Option) (*DescribeLogGroupsOutput, error) {
	req, out := c.DescribeLogGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeLogGroupsPages iterates over the pages of a DescribeLogGroups operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeLogGroups method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeLogGroups operation.
//    pageNum := 0
//    err := client.DescribeLogGroupsPages(params,
//        func(page *cloudwatchlogs.DescribeLogGroupsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) DescribeLogGroupsPages(input *DescribeLogGroupsInput, fn func(*DescribeLogGroupsOutput, bool) bool) error {
	return c.DescribeLogGroupsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeLogGroupsPagesWithContext same as DescribeLogGroupsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeLogGroupsPagesWithContext(ctx aws.Context, input *DescribeLogGroupsInput, fn func(*DescribeLogGroupsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeLogGroupsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeLogGroupsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*DescribeLogGroupsOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opDescribeLogStreams = "DescribeLogStreams"

// DescribeLogStreamsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLogStreams operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLogStreams for more information on using the DescribeLogStreams
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLogStreamsRequest method.
//    req, resp := client.DescribeLogStreamsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeLogStreams
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{}
	}

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

// DescribeLogStreams API operation for Amazon CloudWatch Logs.
//
// Lists the log streams for the specified log group. You can list all the log
// streams or filter the results by prefix. You can also control how the results
// are ordered.
//
// This operation has a limit of five transactions per second, after which transactions
// are throttled.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeLogStreams for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeLogStreams
func (c *CloudWatchLogs) DescribeLogStreams(input *DescribeLogStreamsInput) (*DescribeLogStreamsOutput, error) {
	req, out := c.DescribeLogStreamsRequest(input)
	return out, req.Send()
}

// DescribeLogStreamsWithContext is the same as DescribeLogStreams with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLogStreams for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeLogStreamsWithContext(ctx aws.Context, input *DescribeLogStreamsInput, opts ...request.Option) (*DescribeLogStreamsOutput, error) {
	req, out := c.DescribeLogStreamsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeLogStreamsPages iterates over the pages of a DescribeLogStreams operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeLogStreams method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeLogStreams operation.
//    pageNum := 0
//    err := client.DescribeLogStreamsPages(params,
//        func(page *cloudwatchlogs.DescribeLogStreamsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) DescribeLogStreamsPages(input *DescribeLogStreamsInput, fn func(*DescribeLogStreamsOutput, bool) bool) error {
	return c.DescribeLogStreamsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeLogStreamsPagesWithContext same as DescribeLogStreamsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeLogStreamsPagesWithContext(ctx aws.Context, input *DescribeLogStreamsInput, fn func(*DescribeLogStreamsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeLogStreamsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeLogStreamsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*DescribeLogStreamsOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opDescribeMetricFilters = "DescribeMetricFilters"

// DescribeMetricFiltersRequest generates a "aws/request.Request" representing the
// client's request for the DescribeMetricFilters operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeMetricFilters for more information on using the DescribeMetricFilters
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeMetricFiltersRequest method.
//    req, resp := client.DescribeMetricFiltersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeMetricFilters
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{}
	}

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

// DescribeMetricFilters API operation for Amazon CloudWatch Logs.
//
// Lists the specified metric filters. You can list all the metric filters or
// filter the results by log name, prefix, metric name, or metric namespace.
// The results are ASCII-sorted by filter name.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeMetricFilters for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeMetricFilters
func (c *CloudWatchLogs) DescribeMetricFilters(input *DescribeMetricFiltersInput) (*DescribeMetricFiltersOutput, error) {
	req, out := c.DescribeMetricFiltersRequest(input)
	return out, req.Send()
}

// DescribeMetricFiltersWithContext is the same as DescribeMetricFilters with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeMetricFilters for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeMetricFiltersWithContext(ctx aws.Context, input *DescribeMetricFiltersInput, opts ...request.Option) (*DescribeMetricFiltersOutput, error) {
	req, out := c.DescribeMetricFiltersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeMetricFiltersPages iterates over the pages of a DescribeMetricFilters operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeMetricFilters method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeMetricFilters operation.
//    pageNum := 0
//    err := client.DescribeMetricFiltersPages(params,
//        func(page *cloudwatchlogs.DescribeMetricFiltersOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) DescribeMetricFiltersPages(input *DescribeMetricFiltersInput, fn func(*DescribeMetricFiltersOutput, bool) bool) error {
	return c.DescribeMetricFiltersPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeMetricFiltersPagesWithContext same as DescribeMetricFiltersPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeMetricFiltersPagesWithContext(ctx aws.Context, input *DescribeMetricFiltersInput, fn func(*DescribeMetricFiltersOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeMetricFiltersInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeMetricFiltersRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*DescribeMetricFiltersOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opDescribeQueries = "DescribeQueries"

// DescribeQueriesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeQueries operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeQueries for more information on using the DescribeQueries
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeQueriesRequest method.
//    req, resp := client.DescribeQueriesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeQueries
func (c *CloudWatchLogs) DescribeQueriesRequest(input *DescribeQueriesInput) (req *request.Request, output *DescribeQueriesOutput) {
	op := &request.Operation{
		Name:       opDescribeQueries,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeQueriesInput{}
	}

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

// DescribeQueries API operation for Amazon CloudWatch Logs.
//
// Returns a list of CloudWatch Logs Insights queries that are scheduled, executing,
// or have been executed recently in this account. You can request all queries,
// or limit it to queries of a specific log group or queries with a certain
// status.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeQueries for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeQueries
func (c *CloudWatchLogs) DescribeQueries(input *DescribeQueriesInput) (*DescribeQueriesOutput, error) {
	req, out := c.DescribeQueriesRequest(input)
	return out, req.Send()
}

// DescribeQueriesWithContext is the same as DescribeQueries with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeQueries for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeQueriesWithContext(ctx aws.Context, input *DescribeQueriesInput, opts ...request.Option) (*DescribeQueriesOutput, error) {
	req, out := c.DescribeQueriesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeResourcePolicies = "DescribeResourcePolicies"

// DescribeResourcePoliciesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeResourcePolicies operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeResourcePolicies for more information on using the DescribeResourcePolicies
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeResourcePoliciesRequest method.
//    req, resp := client.DescribeResourcePoliciesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeResourcePolicies
func (c *CloudWatchLogs) DescribeResourcePoliciesRequest(input *DescribeResourcePoliciesInput) (req *request.Request, output *DescribeResourcePoliciesOutput) {
	op := &request.Operation{
		Name:       opDescribeResourcePolicies,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeResourcePoliciesInput{}
	}

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

// DescribeResourcePolicies API operation for Amazon CloudWatch Logs.
//
// Lists the resource policies in this account.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeResourcePolicies for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeResourcePolicies
func (c *CloudWatchLogs) DescribeResourcePolicies(input *DescribeResourcePoliciesInput) (*DescribeResourcePoliciesOutput, error) {
	req, out := c.DescribeResourcePoliciesRequest(input)
	return out, req.Send()
}

// DescribeResourcePoliciesWithContext is the same as DescribeResourcePolicies with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeResourcePolicies for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeResourcePoliciesWithContext(ctx aws.Context, input *DescribeResourcePoliciesInput, opts ...request.Option) (*DescribeResourcePoliciesOutput, error) {
	req, out := c.DescribeResourcePoliciesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeSubscriptionFilters = "DescribeSubscriptionFilters"

// DescribeSubscriptionFiltersRequest generates a "aws/request.Request" representing the
// client's request for the DescribeSubscriptionFilters operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeSubscriptionFilters for more information on using the DescribeSubscriptionFilters
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeSubscriptionFiltersRequest method.
//    req, resp := client.DescribeSubscriptionFiltersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeSubscriptionFilters
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{}
	}

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

// DescribeSubscriptionFilters API operation for Amazon CloudWatch Logs.
//
// Lists the subscription filters for the specified log group. You can list
// all the subscription filters or filter the results by prefix. The results
// are ASCII-sorted by filter name.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DescribeSubscriptionFilters for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeSubscriptionFilters
func (c *CloudWatchLogs) DescribeSubscriptionFilters(input *DescribeSubscriptionFiltersInput) (*DescribeSubscriptionFiltersOutput, error) {
	req, out := c.DescribeSubscriptionFiltersRequest(input)
	return out, req.Send()
}

// DescribeSubscriptionFiltersWithContext is the same as DescribeSubscriptionFilters with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeSubscriptionFilters for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeSubscriptionFiltersWithContext(ctx aws.Context, input *DescribeSubscriptionFiltersInput, opts ...request.Option) (*DescribeSubscriptionFiltersOutput, error) {
	req, out := c.DescribeSubscriptionFiltersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeSubscriptionFiltersPages iterates over the pages of a DescribeSubscriptionFilters operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeSubscriptionFilters method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeSubscriptionFilters operation.
//    pageNum := 0
//    err := client.DescribeSubscriptionFiltersPages(params,
//        func(page *cloudwatchlogs.DescribeSubscriptionFiltersOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) DescribeSubscriptionFiltersPages(input *DescribeSubscriptionFiltersInput, fn func(*DescribeSubscriptionFiltersOutput, bool) bool) error {
	return c.DescribeSubscriptionFiltersPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeSubscriptionFiltersPagesWithContext same as DescribeSubscriptionFiltersPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DescribeSubscriptionFiltersPagesWithContext(ctx aws.Context, input *DescribeSubscriptionFiltersInput, fn func(*DescribeSubscriptionFiltersOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeSubscriptionFiltersInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeSubscriptionFiltersRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*DescribeSubscriptionFiltersOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opDisassociateKmsKey = "DisassociateKmsKey"

// DisassociateKmsKeyRequest generates a "aws/request.Request" representing the
// client's request for the DisassociateKmsKey operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DisassociateKmsKey for more information on using the DisassociateKmsKey
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DisassociateKmsKeyRequest method.
//    req, resp := client.DisassociateKmsKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DisassociateKmsKey
func (c *CloudWatchLogs) DisassociateKmsKeyRequest(input *DisassociateKmsKeyInput) (req *request.Request, output *DisassociateKmsKeyOutput) {
	op := &request.Operation{
		Name:       opDisassociateKmsKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisassociateKmsKeyInput{}
	}

	output = &DisassociateKmsKeyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DisassociateKmsKey API operation for Amazon CloudWatch Logs.
//
// Disassociates the associated AWS Key Management Service (AWS KMS) customer
// master key (CMK) from the specified log group.
//
// After the AWS KMS CMK is disassociated from the log group, AWS CloudWatch
// Logs stops encrypting newly ingested data for the log group. All previously
// ingested data remains encrypted, and AWS CloudWatch Logs requires permissions
// for the CMK whenever the encrypted data is requested.
//
// Note that it can take up to 5 minutes for this operation to take effect.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation DisassociateKmsKey for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DisassociateKmsKey
func (c *CloudWatchLogs) DisassociateKmsKey(input *DisassociateKmsKeyInput) (*DisassociateKmsKeyOutput, error) {
	req, out := c.DisassociateKmsKeyRequest(input)
	return out, req.Send()
}

// DisassociateKmsKeyWithContext is the same as DisassociateKmsKey with the addition of
// the ability to pass a context and additional request options.
//
// See DisassociateKmsKey for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) DisassociateKmsKeyWithContext(ctx aws.Context, input *DisassociateKmsKeyInput, opts ...request.Option) (*DisassociateKmsKeyOutput, error) {
	req, out := c.DisassociateKmsKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opFilterLogEvents = "FilterLogEvents"

// FilterLogEventsRequest generates a "aws/request.Request" representing the
// client's request for the FilterLogEvents operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See FilterLogEvents for more information on using the FilterLogEvents
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the FilterLogEventsRequest method.
//    req, resp := client.FilterLogEventsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/FilterLogEvents
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{}
	}

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

// FilterLogEvents API operation for Amazon CloudWatch Logs.
//
// Lists log events from the specified log group. You can list all the log events
// or filter the results using a filter pattern, a time range, and the name
// of the log stream.
//
// By default, this operation returns as many log events as can fit in 1 MB
// (up to 10,000 log events), or all the events found within the time range
// that you specify. If the results include a token, then there are more log
// events available, and you can get additional results by specifying the token
// in a subsequent call.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation FilterLogEvents for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/FilterLogEvents
func (c *CloudWatchLogs) FilterLogEvents(input *FilterLogEventsInput) (*FilterLogEventsOutput, error) {
	req, out := c.FilterLogEventsRequest(input)
	return out, req.Send()
}

// FilterLogEventsWithContext is the same as FilterLogEvents with the addition of
// the ability to pass a context and additional request options.
//
// See FilterLogEvents for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) FilterLogEventsWithContext(ctx aws.Context, input *FilterLogEventsInput, opts ...request.Option) (*FilterLogEventsOutput, error) {
	req, out := c.FilterLogEventsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// FilterLogEventsPages iterates over the pages of a FilterLogEvents operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See FilterLogEvents method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a FilterLogEvents operation.
//    pageNum := 0
//    err := client.FilterLogEventsPages(params,
//        func(page *cloudwatchlogs.FilterLogEventsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) FilterLogEventsPages(input *FilterLogEventsInput, fn func(*FilterLogEventsOutput, bool) bool) error {
	return c.FilterLogEventsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// FilterLogEventsPagesWithContext same as FilterLogEventsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) FilterLogEventsPagesWithContext(ctx aws.Context, input *FilterLogEventsInput, fn func(*FilterLogEventsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *FilterLogEventsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.FilterLogEventsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*FilterLogEventsOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opGetLogEvents = "GetLogEvents"

// GetLogEventsRequest generates a "aws/request.Request" representing the
// client's request for the GetLogEvents operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetLogEvents for more information on using the GetLogEvents
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetLogEventsRequest method.
//    req, resp := client.GetLogEventsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogEvents
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{}
	}

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

// GetLogEvents API operation for Amazon CloudWatch Logs.
//
// Lists log events from the specified log stream. You can list all the log
// events or filter using a time range.
//
// By default, this operation returns as many log events as can fit in a response
// size of 1MB (up to 10,000 log events). You can get additional log events
// by specifying one of the tokens in a subsequent call.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation GetLogEvents for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogEvents
func (c *CloudWatchLogs) GetLogEvents(input *GetLogEventsInput) (*GetLogEventsOutput, error) {
	req, out := c.GetLogEventsRequest(input)
	return out, req.Send()
}

// GetLogEventsWithContext is the same as GetLogEvents with the addition of
// the ability to pass a context and additional request options.
//
// See GetLogEvents for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) GetLogEventsWithContext(ctx aws.Context, input *GetLogEventsInput, opts ...request.Option) (*GetLogEventsOutput, error) {
	req, out := c.GetLogEventsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// GetLogEventsPages iterates over the pages of a GetLogEvents operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See GetLogEvents method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a GetLogEvents operation.
//    pageNum := 0
//    err := client.GetLogEventsPages(params,
//        func(page *cloudwatchlogs.GetLogEventsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *CloudWatchLogs) GetLogEventsPages(input *GetLogEventsInput, fn func(*GetLogEventsOutput, bool) bool) error {
	return c.GetLogEventsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// GetLogEventsPagesWithContext same as GetLogEventsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) GetLogEventsPagesWithContext(ctx aws.Context, input *GetLogEventsInput, fn func(*GetLogEventsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		EndPageOnSameToken: true,
		NewRequest: func() (*request.Request, error) {
			var inCpy *GetLogEventsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.GetLogEventsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	for p.Next() {
		if !fn(p.Page().(*GetLogEventsOutput), !p.HasNextPage()) {
			break
		}
	}

	return p.Err()
}

const opGetLogGroupFields = "GetLogGroupFields"

// GetLogGroupFieldsRequest generates a "aws/request.Request" representing the
// client's request for the GetLogGroupFields operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetLogGroupFields for more information on using the GetLogGroupFields
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetLogGroupFieldsRequest method.
//    req, resp := client.GetLogGroupFieldsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogGroupFields
func (c *CloudWatchLogs) GetLogGroupFieldsRequest(input *GetLogGroupFieldsInput) (req *request.Request, output *GetLogGroupFieldsOutput) {
	op := &request.Operation{
		Name:       opGetLogGroupFields,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetLogGroupFieldsInput{}
	}

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

// GetLogGroupFields API operation for Amazon CloudWatch Logs.
//
// Returns a list of the fields that are included in log events in the specified
// log group, along with the percentage of log events that contain each field.
// The search is limited to a time period that you specify.
//
// In the results, fields that start with @ are fields generated by CloudWatch
// Logs. For example, @timestamp is the timestamp of each log event.
//
// The response results are sorted by the frequency percentage, starting with
// the highest percentage.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation GetLogGroupFields for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogGroupFields
func (c *CloudWatchLogs) GetLogGroupFields(input *GetLogGroupFieldsInput) (*GetLogGroupFieldsOutput, error) {
	req, out := c.GetLogGroupFieldsRequest(input)
	return out, req.Send()
}

// GetLogGroupFieldsWithContext is the same as GetLogGroupFields with the addition of
// the ability to pass a context and additional request options.
//
// See GetLogGroupFields for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) GetLogGroupFieldsWithContext(ctx aws.Context, input *GetLogGroupFieldsInput, opts ...request.Option) (*GetLogGroupFieldsOutput, error) {
	req, out := c.GetLogGroupFieldsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetLogRecord = "GetLogRecord"

// GetLogRecordRequest generates a "aws/request.Request" representing the
// client's request for the GetLogRecord operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetLogRecord for more information on using the GetLogRecord
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetLogRecordRequest method.
//    req, resp := client.GetLogRecordRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogRecord
func (c *CloudWatchLogs) GetLogRecordRequest(input *GetLogRecordInput) (req *request.Request, output *GetLogRecordOutput) {
	op := &request.Operation{
		Name:       opGetLogRecord,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetLogRecordInput{}
	}

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

// GetLogRecord API operation for Amazon CloudWatch Logs.
//
// Retrieves all the fields and values of a single log event. All fields are
// retrieved, even if the original query that produced the logRecordPointer
// retrieved only a subset of fields. Fields are returned as field name/field
// value pairs.
//
// Additionally, the entire unparsed log event is returned within @message.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation GetLogRecord for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetLogRecord
func (c *CloudWatchLogs) GetLogRecord(input *GetLogRecordInput) (*GetLogRecordOutput, error) {
	req, out := c.GetLogRecordRequest(input)
	return out, req.Send()
}

// GetLogRecordWithContext is the same as GetLogRecord with the addition of
// the ability to pass a context and additional request options.
//
// See GetLogRecord for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) GetLogRecordWithContext(ctx aws.Context, input *GetLogRecordInput, opts ...request.Option) (*GetLogRecordOutput, error) {
	req, out := c.GetLogRecordRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetQueryResults = "GetQueryResults"

// GetQueryResultsRequest generates a "aws/request.Request" representing the
// client's request for the GetQueryResults operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetQueryResults for more information on using the GetQueryResults
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetQueryResultsRequest method.
//    req, resp := client.GetQueryResultsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetQueryResults
func (c *CloudWatchLogs) GetQueryResultsRequest(input *GetQueryResultsInput) (req *request.Request, output *GetQueryResultsOutput) {
	op := &request.Operation{
		Name:       opGetQueryResults,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetQueryResultsInput{}
	}

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

// GetQueryResults API operation for Amazon CloudWatch Logs.
//
// Returns the results from the specified query.
//
// Only the fields requested in the query are returned, along with a @ptr field
// which is the identifier for the log record. You can use the value of @ptr
// in a operation to get the full log record.
//
// GetQueryResults does not start a query execution. To run a query, use .
//
// If the value of the Status field in the output is Running, this operation
// returns only partial results. If you see a value of Scheduled or Running
// for the status, you can retry the operation later to see the final results.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation GetQueryResults for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/GetQueryResults
func (c *CloudWatchLogs) GetQueryResults(input *GetQueryResultsInput) (*GetQueryResultsOutput, error) {
	req, out := c.GetQueryResultsRequest(input)
	return out, req.Send()
}

// GetQueryResultsWithContext is the same as GetQueryResults with the addition of
// the ability to pass a context and additional request options.
//
// See GetQueryResults for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) GetQueryResultsWithContext(ctx aws.Context, input *GetQueryResultsInput, opts ...request.Option) (*GetQueryResultsOutput, error) {
	req, out := c.GetQueryResultsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opListTagsLogGroup = "ListTagsLogGroup"

// ListTagsLogGroupRequest generates a "aws/request.Request" representing the
// client's request for the ListTagsLogGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ListTagsLogGroup for more information on using the ListTagsLogGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ListTagsLogGroupRequest method.
//    req, resp := client.ListTagsLogGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/ListTagsLogGroup
func (c *CloudWatchLogs) ListTagsLogGroupRequest(input *ListTagsLogGroupInput) (req *request.Request, output *ListTagsLogGroupOutput) {
	op := &request.Operation{
		Name:       opListTagsLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ListTagsLogGroupInput{}
	}

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

// ListTagsLogGroup API operation for Amazon CloudWatch Logs.
//
// Lists the tags for the specified log group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation ListTagsLogGroup for usage and error information.
//
// Returned Error Types:
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/ListTagsLogGroup
func (c *CloudWatchLogs) ListTagsLogGroup(input *ListTagsLogGroupInput) (*ListTagsLogGroupOutput, error) {
	req, out := c.ListTagsLogGroupRequest(input)
	return out, req.Send()
}

// ListTagsLogGroupWithContext is the same as ListTagsLogGroup with the addition of
// the ability to pass a context and additional request options.
//
// See ListTagsLogGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) ListTagsLogGroupWithContext(ctx aws.Context, input *ListTagsLogGroupInput, opts ...request.Option) (*ListTagsLogGroupOutput, error) {
	req, out := c.ListTagsLogGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutDestination = "PutDestination"

// PutDestinationRequest generates a "aws/request.Request" representing the
// client's request for the PutDestination operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutDestination for more information on using the PutDestination
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutDestinationRequest method.
//    req, resp := client.PutDestinationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutDestination
func (c *CloudWatchLogs) PutDestinationRequest(input *PutDestinationInput) (req *request.Request, output *PutDestinationOutput) {
	op := &request.Operation{
		Name:       opPutDestination,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutDestination API operation for Amazon CloudWatch Logs.
//
// Creates or updates a destination. This operation is used only to create destinations
// for cross-account subscriptions.
//
// A destination encapsulates a physical resource (such as an Amazon Kinesis
// stream) and enables you to subscribe to a real-time stream of log events
// for a different account, ingested using PutLogEvents.
//
// Through an access policy, a destination controls what is written to it. By
// default, PutDestination does not set any access policy with the destination,
// which means a cross-account user cannot call PutSubscriptionFilter against
// this destination. To enable this, the destination owner must call PutDestinationPolicy
// after PutDestination.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutDestination for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutDestination
func (c *CloudWatchLogs) PutDestination(input *PutDestinationInput) (*PutDestinationOutput, error) {
	req, out := c.PutDestinationRequest(input)
	return out, req.Send()
}

// PutDestinationWithContext is the same as PutDestination with the addition of
// the ability to pass a context and additional request options.
//
// See PutDestination for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutDestinationWithContext(ctx aws.Context, input *PutDestinationInput, opts ...request.Option) (*PutDestinationOutput, error) {
	req, out := c.PutDestinationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutDestinationPolicy = "PutDestinationPolicy"

// PutDestinationPolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutDestinationPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutDestinationPolicy for more information on using the PutDestinationPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutDestinationPolicyRequest method.
//    req, resp := client.PutDestinationPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutDestinationPolicy
func (c *CloudWatchLogs) PutDestinationPolicyRequest(input *PutDestinationPolicyInput) (req *request.Request, output *PutDestinationPolicyOutput) {
	op := &request.Operation{
		Name:       opPutDestinationPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutDestinationPolicy API operation for Amazon CloudWatch Logs.
//
// Creates or updates an access policy associated with an existing destination.
// An access policy is an IAM policy document (https://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.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutDestinationPolicy for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutDestinationPolicy
func (c *CloudWatchLogs) PutDestinationPolicy(input *PutDestinationPolicyInput) (*PutDestinationPolicyOutput, error) {
	req, out := c.PutDestinationPolicyRequest(input)
	return out, req.Send()
}

// PutDestinationPolicyWithContext is the same as PutDestinationPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutDestinationPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutDestinationPolicyWithContext(ctx aws.Context, input *PutDestinationPolicyInput, opts ...request.Option) (*PutDestinationPolicyOutput, error) {
	req, out := c.PutDestinationPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutLogEvents = "PutLogEvents"

// PutLogEventsRequest generates a "aws/request.Request" representing the
// client's request for the PutLogEvents operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutLogEvents for more information on using the PutLogEvents
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutLogEventsRequest method.
//    req, resp := client.PutLogEventsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutLogEvents
func (c *CloudWatchLogs) PutLogEventsRequest(input *PutLogEventsInput) (req *request.Request, output *PutLogEventsOutput) {
	op := &request.Operation{
		Name:       opPutLogEvents,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutLogEvents API operation for Amazon CloudWatch Logs.
//
// Uploads a batch of log events to the specified log stream.
//
// You must include the sequence token obtained from the response of the previous
// call. An upload in a newly created log stream does not require a sequence
// token. You can also get the sequence token in the expectedSequenceToken field
// from InvalidSequenceTokenException. If you call PutLogEvents twice within
// a narrow time period using the same value for sequenceToken, both calls may
// be successful, or one may be rejected.
//
// 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 older
//    than the retention period of the log group.
//
//    * The log events in the batch must be in chronological ordered by their
//    timestamp. The timestamp is the time the event occurred, expressed as
//    the number of milliseconds after Jan 1, 1970 00:00:00 UTC. (In AWS Tools
//    for PowerShell and the AWS SDK for .NET, the timestamp is specified in
//    .NET format: yyyy-mm-ddThh:mm:ss. For example, 2017-09-15T13:45:30.)
//
//    * A batch of log events in a single request cannot span more than 24 hours.
//    Otherwise, the operation fails.
//
//    * The maximum number of log events in a batch is 10,000.
//
//    * There is a quota of 5 requests per second per log stream. Additional
//    requests are throttled. This quota can't be changed.
//
// If a call to PutLogEvents returns "UnrecognizedClientException" the most
// likely cause is an invalid AWS access key ID or secret key.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutLogEvents for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * InvalidSequenceTokenException
//   The sequence token is not valid. You can get the correct sequence token in
//   the expectedSequenceToken field in the InvalidSequenceTokenException message.
//
//   * DataAlreadyAcceptedException
//   The event was already logged.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
//   * UnrecognizedClientException
//   The most likely cause is an invalid AWS access key ID or secret key.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutLogEvents
func (c *CloudWatchLogs) PutLogEvents(input *PutLogEventsInput) (*PutLogEventsOutput, error) {
	req, out := c.PutLogEventsRequest(input)
	return out, req.Send()
}

// PutLogEventsWithContext is the same as PutLogEvents with the addition of
// the ability to pass a context and additional request options.
//
// See PutLogEvents for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutLogEventsWithContext(ctx aws.Context, input *PutLogEventsInput, opts ...request.Option) (*PutLogEventsOutput, error) {
	req, out := c.PutLogEventsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutMetricFilter = "PutMetricFilter"

// PutMetricFilterRequest generates a "aws/request.Request" representing the
// client's request for the PutMetricFilter operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutMetricFilter for more information on using the PutMetricFilter
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutMetricFilterRequest method.
//    req, resp := client.PutMetricFilterRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutMetricFilter
func (c *CloudWatchLogs) PutMetricFilterRequest(input *PutMetricFilterInput) (req *request.Request, output *PutMetricFilterOutput) {
	op := &request.Operation{
		Name:       opPutMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutMetricFilter API operation for Amazon CloudWatch Logs.
//
// 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.
//
// The maximum number of metric filters that can be associated with a log group
// is 100.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutMetricFilter for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutMetricFilter
func (c *CloudWatchLogs) PutMetricFilter(input *PutMetricFilterInput) (*PutMetricFilterOutput, error) {
	req, out := c.PutMetricFilterRequest(input)
	return out, req.Send()
}

// PutMetricFilterWithContext is the same as PutMetricFilter with the addition of
// the ability to pass a context and additional request options.
//
// See PutMetricFilter for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutMetricFilterWithContext(ctx aws.Context, input *PutMetricFilterInput, opts ...request.Option) (*PutMetricFilterOutput, error) {
	req, out := c.PutMetricFilterRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutResourcePolicy = "PutResourcePolicy"

// PutResourcePolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutResourcePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutResourcePolicy for more information on using the PutResourcePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutResourcePolicyRequest method.
//    req, resp := client.PutResourcePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutResourcePolicy
func (c *CloudWatchLogs) PutResourcePolicyRequest(input *PutResourcePolicyInput) (req *request.Request, output *PutResourcePolicyOutput) {
	op := &request.Operation{
		Name:       opPutResourcePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutResourcePolicyInput{}
	}

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

// PutResourcePolicy API operation for Amazon CloudWatch Logs.
//
// Creates or updates a resource policy allowing other AWS services to put log
// events to this account, such as Amazon Route 53. An account can have up to
// 10 resource policies per region.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutResourcePolicy for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutResourcePolicy
func (c *CloudWatchLogs) PutResourcePolicy(input *PutResourcePolicyInput) (*PutResourcePolicyOutput, error) {
	req, out := c.PutResourcePolicyRequest(input)
	return out, req.Send()
}

// PutResourcePolicyWithContext is the same as PutResourcePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutResourcePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutResourcePolicyWithContext(ctx aws.Context, input *PutResourcePolicyInput, opts ...request.Option) (*PutResourcePolicyOutput, error) {
	req, out := c.PutResourcePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutRetentionPolicy = "PutRetentionPolicy"

// PutRetentionPolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutRetentionPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutRetentionPolicy for more information on using the PutRetentionPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutRetentionPolicyRequest method.
//    req, resp := client.PutRetentionPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutRetentionPolicy
func (c *CloudWatchLogs) PutRetentionPolicyRequest(input *PutRetentionPolicyInput) (req *request.Request, output *PutRetentionPolicyOutput) {
	op := &request.Operation{
		Name:       opPutRetentionPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutRetentionPolicy API operation for Amazon CloudWatch Logs.
//
// Sets the retention of the specified log group. A retention policy allows
// you to configure the number of days for which to retain log events in the
// specified log group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutRetentionPolicy for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutRetentionPolicy
func (c *CloudWatchLogs) PutRetentionPolicy(input *PutRetentionPolicyInput) (*PutRetentionPolicyOutput, error) {
	req, out := c.PutRetentionPolicyRequest(input)
	return out, req.Send()
}

// PutRetentionPolicyWithContext is the same as PutRetentionPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutRetentionPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutRetentionPolicyWithContext(ctx aws.Context, input *PutRetentionPolicyInput, opts ...request.Option) (*PutRetentionPolicyOutput, error) {
	req, out := c.PutRetentionPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutSubscriptionFilter = "PutSubscriptionFilter"

// PutSubscriptionFilterRequest generates a "aws/request.Request" representing the
// client's request for the PutSubscriptionFilter operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutSubscriptionFilter for more information on using the PutSubscriptionFilter
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutSubscriptionFilterRequest method.
//    req, resp := client.PutSubscriptionFilterRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutSubscriptionFilter
func (c *CloudWatchLogs) PutSubscriptionFilterRequest(input *PutSubscriptionFilterInput) (req *request.Request, output *PutSubscriptionFilterOutput) {
	op := &request.Operation{
		Name:       opPutSubscriptionFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// PutSubscriptionFilter API operation for Amazon CloudWatch Logs.
//
// 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 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 that belongs to a different account, for cross-account
//    delivery.
//
//    * An Amazon Kinesis Firehose delivery stream that belongs to the same
//    account as the subscription filter, for same-account delivery.
//
//    * An AWS Lambda function that belongs to the same account as the subscription
//    filter, for same-account delivery.
//
// There can only be one subscription filter associated with a log group. If
// you are updating an existing filter, you must specify the correct name in
// filterName. Otherwise, the call fails because you cannot associate a second
// filter with a log group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation PutSubscriptionFilter for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * OperationAbortedException
//   Multiple requests to update the same resource were in conflict.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutSubscriptionFilter
func (c *CloudWatchLogs) PutSubscriptionFilter(input *PutSubscriptionFilterInput) (*PutSubscriptionFilterOutput, error) {
	req, out := c.PutSubscriptionFilterRequest(input)
	return out, req.Send()
}

// PutSubscriptionFilterWithContext is the same as PutSubscriptionFilter with the addition of
// the ability to pass a context and additional request options.
//
// See PutSubscriptionFilter for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) PutSubscriptionFilterWithContext(ctx aws.Context, input *PutSubscriptionFilterInput, opts ...request.Option) (*PutSubscriptionFilterOutput, error) {
	req, out := c.PutSubscriptionFilterRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opStartQuery = "StartQuery"

// StartQueryRequest generates a "aws/request.Request" representing the
// client's request for the StartQuery operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See StartQuery for more information on using the StartQuery
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the StartQueryRequest method.
//    req, resp := client.StartQueryRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/StartQuery
func (c *CloudWatchLogs) StartQueryRequest(input *StartQueryInput) (req *request.Request, output *StartQueryOutput) {
	op := &request.Operation{
		Name:       opStartQuery,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &StartQueryInput{}
	}

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

// StartQuery API operation for Amazon CloudWatch Logs.
//
// Schedules a query of a log group using CloudWatch Logs Insights. You specify
// the log group and time range to query, and the query string to use.
//
// For more information, see CloudWatch Logs Insights Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html).
//
// Queries time out after 15 minutes of execution. If your queries are timing
// out, reduce the time range being searched, or partition your query into a
// number of queries.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation StartQuery for usage and error information.
//
// Returned Error Types:
//   * MalformedQueryException
//   The query string is not valid. Details about this error are displayed in
//   a QueryCompileError object. For more information, see .
//
//   For more information about valid query syntax, see CloudWatch Logs Insights
//   Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html).
//
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * LimitExceededException
//   You have reached the maximum number of resources that can be created.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/StartQuery
func (c *CloudWatchLogs) StartQuery(input *StartQueryInput) (*StartQueryOutput, error) {
	req, out := c.StartQueryRequest(input)
	return out, req.Send()
}

// StartQueryWithContext is the same as StartQuery with the addition of
// the ability to pass a context and additional request options.
//
// See StartQuery for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) StartQueryWithContext(ctx aws.Context, input *StartQueryInput, opts ...request.Option) (*StartQueryOutput, error) {
	req, out := c.StartQueryRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opStopQuery = "StopQuery"

// StopQueryRequest generates a "aws/request.Request" representing the
// client's request for the StopQuery operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See StopQuery for more information on using the StopQuery
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the StopQueryRequest method.
//    req, resp := client.StopQueryRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/StopQuery
func (c *CloudWatchLogs) StopQueryRequest(input *StopQueryInput) (req *request.Request, output *StopQueryOutput) {
	op := &request.Operation{
		Name:       opStopQuery,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &StopQueryInput{}
	}

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

// StopQuery API operation for Amazon CloudWatch Logs.
//
// Stops a CloudWatch Logs Insights query that is in progress. If the query
// has already ended, the operation returns an error indicating that the specified
// query is not running.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation StopQuery for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/StopQuery
func (c *CloudWatchLogs) StopQuery(input *StopQueryInput) (*StopQueryOutput, error) {
	req, out := c.StopQueryRequest(input)
	return out, req.Send()
}

// StopQueryWithContext is the same as StopQuery with the addition of
// the ability to pass a context and additional request options.
//
// See StopQuery for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) StopQueryWithContext(ctx aws.Context, input *StopQueryInput, opts ...request.Option) (*StopQueryOutput, error) {
	req, out := c.StopQueryRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opTagLogGroup = "TagLogGroup"

// TagLogGroupRequest generates a "aws/request.Request" representing the
// client's request for the TagLogGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See TagLogGroup for more information on using the TagLogGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the TagLogGroupRequest method.
//    req, resp := client.TagLogGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/TagLogGroup
func (c *CloudWatchLogs) TagLogGroupRequest(input *TagLogGroupInput) (req *request.Request, output *TagLogGroupOutput) {
	op := &request.Operation{
		Name:       opTagLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &TagLogGroupInput{}
	}

	output = &TagLogGroupOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// TagLogGroup API operation for Amazon CloudWatch Logs.
//
// Adds or updates the specified tags for the specified log group.
//
// To list the tags for a log group, use ListTagsLogGroup. To remove tags, use
// UntagLogGroup.
//
// For more information about tags, see Tag Log Groups in Amazon CloudWatch
// Logs (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/log-group-tagging.html)
// in the Amazon CloudWatch Logs User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation TagLogGroup for usage and error information.
//
// Returned Error Types:
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/TagLogGroup
func (c *CloudWatchLogs) TagLogGroup(input *TagLogGroupInput) (*TagLogGroupOutput, error) {
	req, out := c.TagLogGroupRequest(input)
	return out, req.Send()
}

// TagLogGroupWithContext is the same as TagLogGroup with the addition of
// the ability to pass a context and additional request options.
//
// See TagLogGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) TagLogGroupWithContext(ctx aws.Context, input *TagLogGroupInput, opts ...request.Option) (*TagLogGroupOutput, error) {
	req, out := c.TagLogGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opTestMetricFilter = "TestMetricFilter"

// TestMetricFilterRequest generates a "aws/request.Request" representing the
// client's request for the TestMetricFilter operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See TestMetricFilter for more information on using the TestMetricFilter
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the TestMetricFilterRequest method.
//    req, resp := client.TestMetricFilterRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/TestMetricFilter
func (c *CloudWatchLogs) TestMetricFilterRequest(input *TestMetricFilterInput) (req *request.Request, output *TestMetricFilterOutput) {
	op := &request.Operation{
		Name:       opTestMetricFilter,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// TestMetricFilter API operation for Amazon CloudWatch Logs.
//
// 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.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation TestMetricFilter for usage and error information.
//
// Returned Error Types:
//   * InvalidParameterException
//   A parameter is specified incorrectly.
//
//   * ServiceUnavailableException
//   The service cannot complete the request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/TestMetricFilter
func (c *CloudWatchLogs) TestMetricFilter(input *TestMetricFilterInput) (*TestMetricFilterOutput, error) {
	req, out := c.TestMetricFilterRequest(input)
	return out, req.Send()
}

// TestMetricFilterWithContext is the same as TestMetricFilter with the addition of
// the ability to pass a context and additional request options.
//
// See TestMetricFilter for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) TestMetricFilterWithContext(ctx aws.Context, input *TestMetricFilterInput, opts ...request.Option) (*TestMetricFilterOutput, error) {
	req, out := c.TestMetricFilterRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUntagLogGroup = "UntagLogGroup"

// UntagLogGroupRequest generates a "aws/request.Request" representing the
// client's request for the UntagLogGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See UntagLogGroup for more information on using the UntagLogGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the UntagLogGroupRequest method.
//    req, resp := client.UntagLogGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/UntagLogGroup
func (c *CloudWatchLogs) UntagLogGroupRequest(input *UntagLogGroupInput) (req *request.Request, output *UntagLogGroupOutput) {
	op := &request.Operation{
		Name:       opUntagLogGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UntagLogGroupInput{}
	}

	output = &UntagLogGroupOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// UntagLogGroup API operation for Amazon CloudWatch Logs.
//
// Removes the specified tags from the specified log group.
//
// To list the tags for a log group, use ListTagsLogGroup. To add tags, use
// UntagLogGroup.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon CloudWatch Logs's
// API operation UntagLogGroup for usage and error information.
//
// Returned Error Types:
//   * ResourceNotFoundException
//   The specified resource does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/UntagLogGroup
func (c *CloudWatchLogs) UntagLogGroup(input *UntagLogGroupInput) (*UntagLogGroupOutput, error) {
	req, out := c.UntagLogGroupRequest(input)
	return out, req.Send()
}

// UntagLogGroupWithContext is the same as UntagLogGroup with the addition of
// the ability to pass a context and additional request options.
//
// See UntagLogGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *CloudWatchLogs) UntagLogGroupWithContext(ctx aws.Context, input *UntagLogGroupInput, opts ...request.Option) (*UntagLogGroupOutput, error) {
	req, out := c.UntagLogGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

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

	// The Amazon Resource Name (ARN) of the CMK to use when encrypting log data.
	// This must be a symmetric CMK. For more information, see Amazon Resource Names
	// - AWS Key Management Service (AWS KMS) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms)
	// and Using Symmetric and Asymmetric Keys (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html).
	//
	// KmsKeyId is a required field
	KmsKeyId *string `locationName:"kmsKeyId" type:"string" required:"true"`

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

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *AssociateKmsKeyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AssociateKmsKeyInput"}
	if s.KmsKeyId == nil {
		invalidParams.Add(request.NewErrParamRequired("KmsKeyId"))
	}
	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
}

// SetKmsKeyId sets the KmsKeyId field's value.
func (s *AssociateKmsKeyInput) SetKmsKeyId(v string) *AssociateKmsKeyInput {
	s.KmsKeyId = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *AssociateKmsKeyInput) SetLogGroupName(v string) *AssociateKmsKeyInput {
	s.LogGroupName = &v
	return s
}

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

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

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

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

	// The ID of the export task.
	//
	// TaskId is a required field
	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
}

// SetTaskId sets the TaskId field's value.
func (s *CancelExportTaskInput) SetTaskId(v string) *CancelExportTaskInput {
	s.TaskId = &v
	return s
}

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"`

	// The name of S3 bucket for the exported log data. The bucket must be in the
	// same AWS region.
	//
	// Destination is a required field
	Destination *string `locationName:"destination" min:"1" type:"string" required:"true"`

	// The prefix used as the start of the key for every object exported. If you
	// don't specify a value, the default is exportedlogs.
	DestinationPrefix *string `locationName:"destinationPrefix" type:"string"`

	// The start time of the range for the request, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC. Events with a timestamp earlier than this
	// time are not exported.
	//
	// From is a required field
	From *int64 `locationName:"from" type:"long" required:"true"`

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

	// Export only log streams that match the provided prefix. 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"`

	// The end time of the range for the request, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC. Events with a timestamp later than this time
	// are not exported.
	//
	// To is a required field
	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
}

// SetDestination sets the Destination field's value.
func (s *CreateExportTaskInput) SetDestination(v string) *CreateExportTaskInput {
	s.Destination = &v
	return s
}

// SetDestinationPrefix sets the DestinationPrefix field's value.
func (s *CreateExportTaskInput) SetDestinationPrefix(v string) *CreateExportTaskInput {
	s.DestinationPrefix = &v
	return s
}

// SetFrom sets the From field's value.
func (s *CreateExportTaskInput) SetFrom(v int64) *CreateExportTaskInput {
	s.From = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *CreateExportTaskInput) SetLogGroupName(v string) *CreateExportTaskInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamNamePrefix sets the LogStreamNamePrefix field's value.
func (s *CreateExportTaskInput) SetLogStreamNamePrefix(v string) *CreateExportTaskInput {
	s.LogStreamNamePrefix = &v
	return s
}

// SetTaskName sets the TaskName field's value.
func (s *CreateExportTaskInput) SetTaskName(v string) *CreateExportTaskInput {
	s.TaskName = &v
	return s
}

// SetTo sets the To field's value.
func (s *CreateExportTaskInput) SetTo(v int64) *CreateExportTaskInput {
	s.To = &v
	return s
}

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

	// The ID of the export task.
	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()
}

// SetTaskId sets the TaskId field's value.
func (s *CreateExportTaskOutput) SetTaskId(v string) *CreateExportTaskOutput {
	s.TaskId = &v
	return s
}

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

	// The Amazon Resource Name (ARN) of the CMK to use when encrypting log data.
	// For more information, see Amazon Resource Names - AWS Key Management Service
	// (AWS KMS) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms).
	KmsKeyId *string `locationName:"kmsKeyId" type:"string"`

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

	// The key-value pairs to use for the tags.
	Tags map[string]*string `locationName:"tags" min:"1" type:"map"`
}

// 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 s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}

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

// SetKmsKeyId sets the KmsKeyId field's value.
func (s *CreateLogGroupInput) SetKmsKeyId(v string) *CreateLogGroupInput {
	s.KmsKeyId = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *CreateLogGroupInput) SetLogGroupName(v string) *CreateLogGroupInput {
	s.LogGroupName = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *CreateLogGroupInput) SetTags(v map[string]*string) *CreateLogGroupInput {
	s.Tags = v
	return s
}

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.
	//
	// LogGroupName is a required field
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream.
	//
	// LogStreamName is a required field
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *CreateLogStreamInput) SetLogGroupName(v string) *CreateLogStreamInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *CreateLogStreamInput) SetLogStreamName(v string) *CreateLogStreamInput {
	s.LogStreamName = &v
	return s
}

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()
}

// The event was already logged.
type DataAlreadyAcceptedException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	ExpectedSequenceToken *string `locationName:"expectedSequenceToken" min:"1" type:"string"`

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorDataAlreadyAcceptedException(v protocol.ResponseMetadata) error {
	return &DataAlreadyAcceptedException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s DataAlreadyAcceptedException) Code() string {
	return "DataAlreadyAcceptedException"
}

// Message returns the exception's message.
func (s DataAlreadyAcceptedException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s DataAlreadyAcceptedException) OrigErr() error {
	return nil
}

func (s DataAlreadyAcceptedException) Error() string {
	return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String())
}

// Status code returns the HTTP status code for the request's response error.
func (s DataAlreadyAcceptedException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s DataAlreadyAcceptedException) RequestID() string {
	return s.respMetadata.RequestID
}

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

	// The name of the destination.
	//
	// DestinationName is a required field
	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
}

// SetDestinationName sets the DestinationName field's value.
func (s *DeleteDestinationInput) SetDestinationName(v string) *DeleteDestinationInput {
	s.DestinationName = &v
	return s
}

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.
	//
	// LogGroupName is a required field
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DeleteLogGroupInput) SetLogGroupName(v string) *DeleteLogGroupInput {
	s.LogGroupName = &v
	return s
}

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.
	//
	// LogGroupName is a required field
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"`

	// The name of the log stream.
	//
	// LogStreamName is a required field
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DeleteLogStreamInput) SetLogGroupName(v string) *DeleteLogStreamInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *DeleteLogStreamInput) SetLogStreamName(v string) *DeleteLogStreamInput {
	s.LogStreamName = &v
	return s
}

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.
	//
	// FilterName is a required field
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// The name of the log group.
	//
	// LogGroupName is a required field
	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
}

// SetFilterName sets the FilterName field's value.
func (s *DeleteMetricFilterInput) SetFilterName(v string) *DeleteMetricFilterInput {
	s.FilterName = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DeleteMetricFilterInput) SetLogGroupName(v string) *DeleteMetricFilterInput {
	s.LogGroupName = &v
	return s
}

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 DeleteResourcePolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the policy to be revoked. This parameter is required.
	PolicyName *string `locationName:"policyName" type:"string"`
}

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

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

// SetPolicyName sets the PolicyName field's value.
func (s *DeleteResourcePolicyInput) SetPolicyName(v string) *DeleteResourcePolicyInput {
	s.PolicyName = &v
	return s
}

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

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

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

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

	// The name of the log group.
	//
	// LogGroupName is a required field
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DeleteRetentionPolicyInput) SetLogGroupName(v string) *DeleteRetentionPolicyInput {
	s.LogGroupName = &v
	return s
}

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.
	//
	// FilterName is a required field
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

	// The name of the log group.
	//
	// LogGroupName is a required field
	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
}

// SetFilterName sets the FilterName field's value.
func (s *DeleteSubscriptionFilterInput) SetFilterName(v string) *DeleteSubscriptionFilterInput {
	s.FilterName = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DeleteSubscriptionFilterInput) SetLogGroupName(v string) *DeleteSubscriptionFilterInput {
	s.LogGroupName = &v
	return s
}

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"`

	// The prefix to match. If you don't specify a value, no prefix filter is applied.
	DestinationNamePrefix *string `min:"1" type:"string"`

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

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	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
}

// SetDestinationNamePrefix sets the DestinationNamePrefix field's value.
func (s *DescribeDestinationsInput) SetDestinationNamePrefix(v string) *DescribeDestinationsInput {
	s.DestinationNamePrefix = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *DescribeDestinationsInput) SetLimit(v int64) *DescribeDestinationsInput {
	s.Limit = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeDestinationsInput) SetNextToken(v string) *DescribeDestinationsInput {
	s.NextToken = &v
	return s
}

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

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

	// The token for the next set of items to return. 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()
}

// SetDestinations sets the Destinations field's value.
func (s *DescribeDestinationsOutput) SetDestinations(v []*Destination) *DescribeDestinationsOutput {
	s.Destinations = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeDestinationsOutput) SetNextToken(v string) *DescribeDestinationsOutput {
	s.NextToken = &v
	return s
}

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

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

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// The status code of the export task. Specifying a status code filters the
	// results to zero or more export tasks.
	StatusCode *string `locationName:"statusCode" type:"string" enum:"ExportTaskStatusCode"`

	// The ID of the export task. Specifying a task ID filters the results to zero
	// or one export tasks.
	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
}

// SetLimit sets the Limit field's value.
func (s *DescribeExportTasksInput) SetLimit(v int64) *DescribeExportTasksInput {
	s.Limit = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeExportTasksInput) SetNextToken(v string) *DescribeExportTasksInput {
	s.NextToken = &v
	return s
}

// SetStatusCode sets the StatusCode field's value.
func (s *DescribeExportTasksInput) SetStatusCode(v string) *DescribeExportTasksInput {
	s.StatusCode = &v
	return s
}

// SetTaskId sets the TaskId field's value.
func (s *DescribeExportTasksInput) SetTaskId(v string) *DescribeExportTasksInput {
	s.TaskId = &v
	return s
}

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

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

	// The token for the next set of items to return. 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()
}

// SetExportTasks sets the ExportTasks field's value.
func (s *DescribeExportTasksOutput) SetExportTasks(v []*ExportTask) *DescribeExportTasksOutput {
	s.ExportTasks = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeExportTasksOutput) SetNextToken(v string) *DescribeExportTasksOutput {
	s.NextToken = &v
	return s
}

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

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

	// The prefix to match.
	LogGroupNamePrefix *string `locationName:"logGroupNamePrefix" min:"1" type:"string"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	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
}

// SetLimit sets the Limit field's value.
func (s *DescribeLogGroupsInput) SetLimit(v int64) *DescribeLogGroupsInput {
	s.Limit = &v
	return s
}

// SetLogGroupNamePrefix sets the LogGroupNamePrefix field's value.
func (s *DescribeLogGroupsInput) SetLogGroupNamePrefix(v string) *DescribeLogGroupsInput {
	s.LogGroupNamePrefix = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLogGroupsInput) SetNextToken(v string) *DescribeLogGroupsInput {
	s.NextToken = &v
	return s
}

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

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

	// The token for the next set of items to return. 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()
}

// SetLogGroups sets the LogGroups field's value.
func (s *DescribeLogGroupsOutput) SetLogGroups(v []*LogGroup) *DescribeLogGroupsOutput {
	s.LogGroups = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLogGroupsOutput) SetNextToken(v string) *DescribeLogGroupsOutput {
	s.NextToken = &v
	return s
}

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

	// If the value is true, results are returned in descending order. If the value
	// is to false, results are returned in ascending order. The default value is
	// false.
	Descending *bool `locationName:"descending" type:"boolean"`

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

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

	// The prefix to match.
	//
	// If orderBy is LastEventTime,you cannot specify this parameter.
	LogStreamNamePrefix *string `locationName:"logStreamNamePrefix" min:"1" type:"string"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// If the value is LogStreamName, the results are ordered by log stream name.
	// If the value is LastEventTime, the results are ordered by the event time.
	// The default value is LogStreamName.
	//
	// If you order the results by event time, you cannot specify the logStreamNamePrefix
	// parameter.
	//
	// lastEventTimestamp represents the time of the most recent log event in the
	// log stream in CloudWatch Logs. This number is expressed as the number of
	// milliseconds after Jan 1, 1970 00:00:00 UTC. lastEventTimeStamp updates on
	// an eventual consistency basis. It typically updates in less than an hour
	// from ingestion, but may take longer in some rare situations.
	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
}

// SetDescending sets the Descending field's value.
func (s *DescribeLogStreamsInput) SetDescending(v bool) *DescribeLogStreamsInput {
	s.Descending = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *DescribeLogStreamsInput) SetLimit(v int64) *DescribeLogStreamsInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DescribeLogStreamsInput) SetLogGroupName(v string) *DescribeLogStreamsInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamNamePrefix sets the LogStreamNamePrefix field's value.
func (s *DescribeLogStreamsInput) SetLogStreamNamePrefix(v string) *DescribeLogStreamsInput {
	s.LogStreamNamePrefix = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLogStreamsInput) SetNextToken(v string) *DescribeLogStreamsInput {
	s.NextToken = &v
	return s
}

// SetOrderBy sets the OrderBy field's value.
func (s *DescribeLogStreamsInput) SetOrderBy(v string) *DescribeLogStreamsInput {
	s.OrderBy = &v
	return s
}

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

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

	// The token for the next set of items to return. 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()
}

// SetLogStreams sets the LogStreams field's value.
func (s *DescribeLogStreamsOutput) SetLogStreams(v []*LogStream) *DescribeLogStreamsOutput {
	s.LogStreams = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLogStreamsOutput) SetNextToken(v string) *DescribeLogStreamsOutput {
	s.NextToken = &v
	return s
}

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

	// The prefix to match.
	FilterNamePrefix *string `locationName:"filterNamePrefix" min:"1" type:"string"`

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

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

	// Filters results to include only those with the specified metric name. If
	// you include this parameter in your request, you must also include the metricNamespace
	// parameter.
	MetricName *string `locationName:"metricName" type:"string"`

	// Filters results to include only those in the specified namespace. If you
	// include this parameter in your request, you must also include the metricName
	// parameter.
	MetricNamespace *string `locationName:"metricNamespace" type:"string"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	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 && 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
}

// SetFilterNamePrefix sets the FilterNamePrefix field's value.
func (s *DescribeMetricFiltersInput) SetFilterNamePrefix(v string) *DescribeMetricFiltersInput {
	s.FilterNamePrefix = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *DescribeMetricFiltersInput) SetLimit(v int64) *DescribeMetricFiltersInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DescribeMetricFiltersInput) SetLogGroupName(v string) *DescribeMetricFiltersInput {
	s.LogGroupName = &v
	return s
}

// SetMetricName sets the MetricName field's value.
func (s *DescribeMetricFiltersInput) SetMetricName(v string) *DescribeMetricFiltersInput {
	s.MetricName = &v
	return s
}

// SetMetricNamespace sets the MetricNamespace field's value.
func (s *DescribeMetricFiltersInput) SetMetricNamespace(v string) *DescribeMetricFiltersInput {
	s.MetricNamespace = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeMetricFiltersInput) SetNextToken(v string) *DescribeMetricFiltersInput {
	s.NextToken = &v
	return s
}

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

	// The metric filters.
	MetricFilters []*MetricFilter `locationName:"metricFilters" type:"list"`

	// The token for the next set of items to return. 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()
}

// SetMetricFilters sets the MetricFilters field's value.
func (s *DescribeMetricFiltersOutput) SetMetricFilters(v []*MetricFilter) *DescribeMetricFiltersOutput {
	s.MetricFilters = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeMetricFiltersOutput) SetNextToken(v string) *DescribeMetricFiltersOutput {
	s.NextToken = &v
	return s
}

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

	// Limits the returned queries to only those for the specified log group.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	// Limits the number of returned queries to the specified number.
	MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"`

	// The token for the next set of items to return. The token expires after 24
	// hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// Limits the returned queries to only those that have the specified status.
	// Valid values are Cancelled, Complete, Failed, Running, and Scheduled.
	Status *string `locationName:"status" type:"string" enum:"QueryStatus"`
}

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

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

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

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

// SetLogGroupName sets the LogGroupName field's value.
func (s *DescribeQueriesInput) SetLogGroupName(v string) *DescribeQueriesInput {
	s.LogGroupName = &v
	return s
}

// SetMaxResults sets the MaxResults field's value.
func (s *DescribeQueriesInput) SetMaxResults(v int64) *DescribeQueriesInput {
	s.MaxResults = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeQueriesInput) SetNextToken(v string) *DescribeQueriesInput {
	s.NextToken = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *DescribeQueriesInput) SetStatus(v string) *DescribeQueriesInput {
	s.Status = &v
	return s
}

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

	// The token for the next set of items to return. The token expires after 24
	// hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// The list of queries that match the request.
	Queries []*QueryInfo `locationName:"queries" type:"list"`
}

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

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

// SetNextToken sets the NextToken field's value.
func (s *DescribeQueriesOutput) SetNextToken(v string) *DescribeQueriesOutput {
	s.NextToken = &v
	return s
}

// SetQueries sets the Queries field's value.
func (s *DescribeQueriesOutput) SetQueries(v []*QueryInfo) *DescribeQueriesOutput {
	s.Queries = v
	return s
}

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

	// The maximum number of resource policies to be displayed with one call of
	// this API.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The token for the next set of items to return. The token expires after 24
	// hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeResourcePoliciesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeResourcePoliciesInput"}
	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
}

// SetLimit sets the Limit field's value.
func (s *DescribeResourcePoliciesInput) SetLimit(v int64) *DescribeResourcePoliciesInput {
	s.Limit = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeResourcePoliciesInput) SetNextToken(v string) *DescribeResourcePoliciesInput {
	s.NextToken = &v
	return s
}

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

	// The token for the next set of items to return. The token expires after 24
	// hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// The resource policies that exist in this account.
	ResourcePolicies []*ResourcePolicy `locationName:"resourcePolicies" type:"list"`
}

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

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

// SetNextToken sets the NextToken field's value.
func (s *DescribeResourcePoliciesOutput) SetNextToken(v string) *DescribeResourcePoliciesOutput {
	s.NextToken = &v
	return s
}

// SetResourcePolicies sets the ResourcePolicies field's value.
func (s *DescribeResourcePoliciesOutput) SetResourcePolicies(v []*ResourcePolicy) *DescribeResourcePoliciesOutput {
	s.ResourcePolicies = v
	return s
}

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

	// The prefix to match. 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. If you don't specify a value, the default
	// is up to 50 items.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

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

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	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
}

// SetFilterNamePrefix sets the FilterNamePrefix field's value.
func (s *DescribeSubscriptionFiltersInput) SetFilterNamePrefix(v string) *DescribeSubscriptionFiltersInput {
	s.FilterNamePrefix = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *DescribeSubscriptionFiltersInput) SetLimit(v int64) *DescribeSubscriptionFiltersInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DescribeSubscriptionFiltersInput) SetLogGroupName(v string) *DescribeSubscriptionFiltersInput {
	s.LogGroupName = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeSubscriptionFiltersInput) SetNextToken(v string) *DescribeSubscriptionFiltersInput {
	s.NextToken = &v
	return s
}

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

	// The token for the next set of items to return. The token expires after 24
	// hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// The subscription filters.
	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()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeSubscriptionFiltersOutput) SetNextToken(v string) *DescribeSubscriptionFiltersOutput {
	s.NextToken = &v
	return s
}

// SetSubscriptionFilters sets the SubscriptionFilters field's value.
func (s *DescribeSubscriptionFiltersOutput) SetSubscriptionFilters(v []*SubscriptionFilter) *DescribeSubscriptionFiltersOutput {
	s.SubscriptionFilters = v
	return s
}

// Represents a cross-account destination that receives 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"`

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

	// The creation time of the destination, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

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

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

	// The Amazon Resource Name (ARN) of the physical target to where the log events
	// are delivered (for example, 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()
}

// SetAccessPolicy sets the AccessPolicy field's value.
func (s *Destination) SetAccessPolicy(v string) *Destination {
	s.AccessPolicy = &v
	return s
}

// SetArn sets the Arn field's value.
func (s *Destination) SetArn(v string) *Destination {
	s.Arn = &v
	return s
}

// SetCreationTime sets the CreationTime field's value.
func (s *Destination) SetCreationTime(v int64) *Destination {
	s.CreationTime = &v
	return s
}

// SetDestinationName sets the DestinationName field's value.
func (s *Destination) SetDestinationName(v string) *Destination {
	s.DestinationName = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *Destination) SetRoleArn(v string) *Destination {
	s.RoleArn = &v
	return s
}

// SetTargetArn sets the TargetArn field's value.
func (s *Destination) SetTargetArn(v string) *Destination {
	s.TargetArn = &v
	return s
}

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

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

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DisassociateKmsKeyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DisassociateKmsKeyInput"}
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *DisassociateKmsKeyInput) SetLogGroupName(v string) *DisassociateKmsKeyInput {
	s.LogGroupName = &v
	return s
}

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

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

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

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

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

	// The 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"`

	// The start time, expressed as the number of milliseconds after Jan 1, 1970
	// 00:00:00 UTC. Events with a timestamp before 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"`

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

	// The 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"`

	// The end time, expressed as the number of milliseconds after 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()
}

// SetDestination sets the Destination field's value.
func (s *ExportTask) SetDestination(v string) *ExportTask {
	s.Destination = &v
	return s
}

// SetDestinationPrefix sets the DestinationPrefix field's value.
func (s *ExportTask) SetDestinationPrefix(v string) *ExportTask {
	s.DestinationPrefix = &v
	return s
}

// SetExecutionInfo sets the ExecutionInfo field's value.
func (s *ExportTask) SetExecutionInfo(v *ExportTaskExecutionInfo) *ExportTask {
	s.ExecutionInfo = v
	return s
}

// SetFrom sets the From field's value.
func (s *ExportTask) SetFrom(v int64) *ExportTask {
	s.From = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *ExportTask) SetLogGroupName(v string) *ExportTask {
	s.LogGroupName = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *ExportTask) SetStatus(v *ExportTaskStatus) *ExportTask {
	s.Status = v
	return s
}

// SetTaskId sets the TaskId field's value.
func (s *ExportTask) SetTaskId(v string) *ExportTask {
	s.TaskId = &v
	return s
}

// SetTaskName sets the TaskName field's value.
func (s *ExportTask) SetTaskName(v string) *ExportTask {
	s.TaskName = &v
	return s
}

// SetTo sets the To field's value.
func (s *ExportTask) SetTo(v int64) *ExportTask {
	s.To = &v
	return s
}

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

	// The completion time of the export task, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	CompletionTime *int64 `locationName:"completionTime" type:"long"`

	// The creation time of the export task, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	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()
}

// SetCompletionTime sets the CompletionTime field's value.
func (s *ExportTaskExecutionInfo) SetCompletionTime(v int64) *ExportTaskExecutionInfo {
	s.CompletionTime = &v
	return s
}

// SetCreationTime sets the CreationTime field's value.
func (s *ExportTaskExecutionInfo) SetCreationTime(v int64) *ExportTaskExecutionInfo {
	s.CreationTime = &v
	return s
}

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

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

	// The status message related to the status 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()
}

// SetCode sets the Code field's value.
func (s *ExportTaskStatus) SetCode(v string) *ExportTaskStatus {
	s.Code = &v
	return s
}

// SetMessage sets the Message field's value.
func (s *ExportTaskStatus) SetMessage(v string) *ExportTaskStatus {
	s.Message = &v
	return s
}

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

	// The end of the time range, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC. Events with a timestamp later than this time are
	// not returned.
	EndTime *int64 `locationName:"endTime" type:"long"`

	// The filter pattern to use. For more information, see Filter and Pattern Syntax
	// (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html).
	//
	// If not provided, all the events are matched.
	FilterPattern *string `locationName:"filterPattern" type:"string"`

	// If the value is true, the operation makes a best effort to provide responses
	// that contain events from multiple log streams within the log group, interleaved
	// in a single response. If the value is false, all the matched log events in
	// the first log stream are searched first, then those in the next log stream,
	// and so on. The default is false.
	//
	// IMPORTANT: Starting on June 17, 2019, this parameter will be ignored and
	// the value will be assumed to be true. The response from this operation will
	// always interleave events from multiple log streams within a log group.
	//
	// Deprecated: Starting on June 17, 2019, this parameter will be ignored and the value will be assumed to be true. The response from this operation will always interleave events from multiple log streams within a log group.
	Interleaved *bool `locationName:"interleaved" deprecated:"true" type:"boolean"`

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

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

	// Filters the results to include only events from log streams that have names
	// starting with this prefix.
	//
	// If you specify a value for both logStreamNamePrefix and logStreamNames, but
	// the value for logStreamNamePrefix does not match any log stream names specified
	// in logStreamNames, the action returns an InvalidParameterException error.
	LogStreamNamePrefix *string `locationName:"logStreamNamePrefix" min:"1" type:"string"`

	// Filters the results to only logs from the log streams in this list.
	//
	// If you specify a value for both logStreamNamePrefix and logStreamNames, the
	// action returns an InvalidParameterException error.
	LogStreamNames []*string `locationName:"logStreamNames" min:"1" type:"list"`

	// The token for the next set of events to return. (You received this token
	// from a previous call.)
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// The start of the time range, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC. Events with a timestamp before 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.LogStreamNamePrefix != nil && len(*s.LogStreamNamePrefix) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LogStreamNamePrefix", 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
}

// SetEndTime sets the EndTime field's value.
func (s *FilterLogEventsInput) SetEndTime(v int64) *FilterLogEventsInput {
	s.EndTime = &v
	return s
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *FilterLogEventsInput) SetFilterPattern(v string) *FilterLogEventsInput {
	s.FilterPattern = &v
	return s
}

// SetInterleaved sets the Interleaved field's value.
func (s *FilterLogEventsInput) SetInterleaved(v bool) *FilterLogEventsInput {
	s.Interleaved = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *FilterLogEventsInput) SetLimit(v int64) *FilterLogEventsInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *FilterLogEventsInput) SetLogGroupName(v string) *FilterLogEventsInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamNamePrefix sets the LogStreamNamePrefix field's value.
func (s *FilterLogEventsInput) SetLogStreamNamePrefix(v string) *FilterLogEventsInput {
	s.LogStreamNamePrefix = &v
	return s
}

// SetLogStreamNames sets the LogStreamNames field's value.
func (s *FilterLogEventsInput) SetLogStreamNames(v []*string) *FilterLogEventsInput {
	s.LogStreamNames = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *FilterLogEventsInput) SetNextToken(v string) *FilterLogEventsInput {
	s.NextToken = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *FilterLogEventsInput) SetStartTime(v int64) *FilterLogEventsInput {
	s.StartTime = &v
	return s
}

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

	// The matched events.
	Events []*FilteredLogEvent `locationName:"events" type:"list"`

	// The token to use when requesting the next set of items. The token expires
	// after 24 hours.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// Indicates which log streams have been searched and whether each has been
	// searched completely.
	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()
}

// SetEvents sets the Events field's value.
func (s *FilterLogEventsOutput) SetEvents(v []*FilteredLogEvent) *FilterLogEventsOutput {
	s.Events = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *FilterLogEventsOutput) SetNextToken(v string) *FilterLogEventsOutput {
	s.NextToken = &v
	return s
}

// SetSearchedLogStreams sets the SearchedLogStreams field's value.
func (s *FilterLogEventsOutput) SetSearchedLogStreams(v []*SearchedLogStream) *FilterLogEventsOutput {
	s.SearchedLogStreams = v
	return s
}

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

	// The ID of the event.
	EventId *string `locationName:"eventId" type:"string"`

	// The time the event was ingested, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	IngestionTime *int64 `locationName:"ingestionTime" type:"long"`

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

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

	// The time the event occurred, expressed as the number of milliseconds after
	// 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()
}

// SetEventId sets the EventId field's value.
func (s *FilteredLogEvent) SetEventId(v string) *FilteredLogEvent {
	s.EventId = &v
	return s
}

// SetIngestionTime sets the IngestionTime field's value.
func (s *FilteredLogEvent) SetIngestionTime(v int64) *FilteredLogEvent {
	s.IngestionTime = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *FilteredLogEvent) SetLogStreamName(v string) *FilteredLogEvent {
	s.LogStreamName = &v
	return s
}

// SetMessage sets the Message field's value.
func (s *FilteredLogEvent) SetMessage(v string) *FilteredLogEvent {
	s.Message = &v
	return s
}

// SetTimestamp sets the Timestamp field's value.
func (s *FilteredLogEvent) SetTimestamp(v int64) *FilteredLogEvent {
	s.Timestamp = &v
	return s
}

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

	// The end of the time range, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC. Events with a timestamp equal to or later than
	// this time are not included.
	EndTime *int64 `locationName:"endTime" type:"long"`

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

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

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

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	//
	// Using this token works only when you specify true for startFromHead.
	NextToken *string `locationName:"nextToken" min:"1" type:"string"`

	// If the value is true, the earliest log events are returned first. If the
	// value is false, the latest log events are returned first. The default value
	// is false.
	//
	// If you are using nextToken in this operation, you must specify true for startFromHead.
	StartFromHead *bool `locationName:"startFromHead" type:"boolean"`

	// The start of the time range, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC. Events with a timestamp equal to this time or later
	// than this time are included. Events with a timestamp earlier than this time
	// are not included.
	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
}

// SetEndTime sets the EndTime field's value.
func (s *GetLogEventsInput) SetEndTime(v int64) *GetLogEventsInput {
	s.EndTime = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *GetLogEventsInput) SetLimit(v int64) *GetLogEventsInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *GetLogEventsInput) SetLogGroupName(v string) *GetLogEventsInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *GetLogEventsInput) SetLogStreamName(v string) *GetLogEventsInput {
	s.LogStreamName = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *GetLogEventsInput) SetNextToken(v string) *GetLogEventsInput {
	s.NextToken = &v
	return s
}

// SetStartFromHead sets the StartFromHead field's value.
func (s *GetLogEventsInput) SetStartFromHead(v bool) *GetLogEventsInput {
	s.StartFromHead = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *GetLogEventsInput) SetStartTime(v int64) *GetLogEventsInput {
	s.StartTime = &v
	return s
}

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

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

	// The token for the next set of items in the backward direction. The token
	// expires after 24 hours. This token will never be null. If you have reached
	// the end of the stream, it will return the same token you passed in.
	NextBackwardToken *string `locationName:"nextBackwardToken" min:"1" type:"string"`

	// The token for the next set of items in the forward direction. The token expires
	// after 24 hours. If you have reached the end of the stream, it will return
	// the same token you passed in.
	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()
}

// SetEvents sets the Events field's value.
func (s *GetLogEventsOutput) SetEvents(v []*OutputLogEvent) *GetLogEventsOutput {
	s.Events = v
	return s
}

// SetNextBackwardToken sets the NextBackwardToken field's value.
func (s *GetLogEventsOutput) SetNextBackwardToken(v string) *GetLogEventsOutput {
	s.NextBackwardToken = &v
	return s
}

// SetNextForwardToken sets the NextForwardToken field's value.
func (s *GetLogEventsOutput) SetNextForwardToken(v string) *GetLogEventsOutput {
	s.NextForwardToken = &v
	return s
}

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

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

	// The time to set as the center of the query. If you specify time, the 8 minutes
	// before and 8 minutes after this time are searched. If you omit time, the
	// past 15 minutes are queried.
	//
	// The time value is specified as epoch time, the number of seconds since January
	// 1, 1970, 00:00:00 UTC.
	Time *int64 `locationName:"time" type:"long"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetLogGroupFieldsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetLogGroupFieldsInput"}
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *GetLogGroupFieldsInput) SetLogGroupName(v string) *GetLogGroupFieldsInput {
	s.LogGroupName = &v
	return s
}

// SetTime sets the Time field's value.
func (s *GetLogGroupFieldsInput) SetTime(v int64) *GetLogGroupFieldsInput {
	s.Time = &v
	return s
}

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

	// The array of fields found in the query. Each object in the array contains
	// the name of the field, along with the percentage of time it appeared in the
	// log events that were queried.
	LogGroupFields []*LogGroupField `locationName:"logGroupFields" type:"list"`
}

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

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

// SetLogGroupFields sets the LogGroupFields field's value.
func (s *GetLogGroupFieldsOutput) SetLogGroupFields(v []*LogGroupField) *GetLogGroupFieldsOutput {
	s.LogGroupFields = v
	return s
}

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

	// The pointer corresponding to the log event record you want to retrieve. You
	// get this from the response of a GetQueryResults operation. In that response,
	// the value of the @ptr field for a log event is the value to use as logRecordPointer
	// to retrieve that complete log event record.
	//
	// LogRecordPointer is a required field
	LogRecordPointer *string `locationName:"logRecordPointer" type:"string" required:"true"`
}

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

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

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

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

// SetLogRecordPointer sets the LogRecordPointer field's value.
func (s *GetLogRecordInput) SetLogRecordPointer(v string) *GetLogRecordInput {
	s.LogRecordPointer = &v
	return s
}

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

	// The requested log event, as a JSON string.
	LogRecord map[string]*string `locationName:"logRecord" type:"map"`
}

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

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

// SetLogRecord sets the LogRecord field's value.
func (s *GetLogRecordOutput) SetLogRecord(v map[string]*string) *GetLogRecordOutput {
	s.LogRecord = v
	return s
}

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

	// The ID number of the query.
	//
	// QueryId is a required field
	QueryId *string `locationName:"queryId" type:"string" required:"true"`
}

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

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

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

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

// SetQueryId sets the QueryId field's value.
func (s *GetQueryResultsInput) SetQueryId(v string) *GetQueryResultsInput {
	s.QueryId = &v
	return s
}

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

	// The log events that matched the query criteria during the most recent time
	// it ran.
	//
	// The results value is an array of arrays. Each log event is one object in
	// the top-level array. Each of these log event objects is an array of field/value
	// pairs.
	Results [][]*ResultField `locationName:"results" type:"list"`

	// Includes the number of log events scanned by the query, the number of log
	// events that matched the query criteria, and the total number of bytes in
	// the log events that were scanned.
	Statistics *QueryStatistics `locationName:"statistics" type:"structure"`

	// The status of the most recent running of the query. Possible values are Cancelled,
	// Complete, Failed, Running, Scheduled, Timeout, and Unknown.
	//
	// Queries time out after 15 minutes of execution. To avoid having your queries
	// time out, reduce the time range being searched, or partition your query into
	// a number of queries.
	Status *string `locationName:"status" type:"string" enum:"QueryStatus"`
}

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

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

// SetResults sets the Results field's value.
func (s *GetQueryResultsOutput) SetResults(v [][]*ResultField) *GetQueryResultsOutput {
	s.Results = v
	return s
}

// SetStatistics sets the Statistics field's value.
func (s *GetQueryResultsOutput) SetStatistics(v *QueryStatistics) *GetQueryResultsOutput {
	s.Statistics = v
	return s
}

// SetStatus sets the Status field's value.
func (s *GetQueryResultsOutput) SetStatus(v string) *GetQueryResultsOutput {
	s.Status = &v
	return s
}

// Represents a log event, which is a record of activity that was recorded by
// the application or resource being monitored.
type InputLogEvent struct {
	_ struct{} `type:"structure"`

	// The raw event message.
	//
	// Message is a required field
	Message *string `locationName:"message" min:"1" type:"string" required:"true"`

	// The time the event occurred, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC.
	//
	// Timestamp is a required field
	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
}

// SetMessage sets the Message field's value.
func (s *InputLogEvent) SetMessage(v string) *InputLogEvent {
	s.Message = &v
	return s
}

// SetTimestamp sets the Timestamp field's value.
func (s *InputLogEvent) SetTimestamp(v int64) *InputLogEvent {
	s.Timestamp = &v
	return s
}

// The operation is not valid on the specified resource.
type InvalidOperationException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorInvalidOperationException(v protocol.ResponseMetadata) error {
	return &InvalidOperationException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s InvalidOperationException) Code() string {
	return "InvalidOperationException"
}

// Message returns the exception's message.
func (s InvalidOperationException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s InvalidOperationException) OrigErr() error {
	return nil
}

func (s InvalidOperationException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s InvalidOperationException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s InvalidOperationException) RequestID() string {
	return s.respMetadata.RequestID
}

// A parameter is specified incorrectly.
type InvalidParameterException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorInvalidParameterException(v protocol.ResponseMetadata) error {
	return &InvalidParameterException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s InvalidParameterException) Code() string {
	return "InvalidParameterException"
}

// Message returns the exception's message.
func (s InvalidParameterException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s InvalidParameterException) OrigErr() error {
	return nil
}

func (s InvalidParameterException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s InvalidParameterException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s InvalidParameterException) RequestID() string {
	return s.respMetadata.RequestID
}

// The sequence token is not valid. You can get the correct sequence token in
// the expectedSequenceToken field in the InvalidSequenceTokenException message.
type InvalidSequenceTokenException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	ExpectedSequenceToken *string `locationName:"expectedSequenceToken" min:"1" type:"string"`

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorInvalidSequenceTokenException(v protocol.ResponseMetadata) error {
	return &InvalidSequenceTokenException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s InvalidSequenceTokenException) Code() string {
	return "InvalidSequenceTokenException"
}

// Message returns the exception's message.
func (s InvalidSequenceTokenException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s InvalidSequenceTokenException) OrigErr() error {
	return nil
}

func (s InvalidSequenceTokenException) Error() string {
	return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String())
}

// Status code returns the HTTP status code for the request's response error.
func (s InvalidSequenceTokenException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s InvalidSequenceTokenException) RequestID() string {
	return s.respMetadata.RequestID
}

// You have reached the maximum number of resources that can be created.
type LimitExceededException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorLimitExceededException(v protocol.ResponseMetadata) error {
	return &LimitExceededException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s LimitExceededException) Code() string {
	return "LimitExceededException"
}

// Message returns the exception's message.
func (s LimitExceededException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s LimitExceededException) OrigErr() error {
	return nil
}

func (s LimitExceededException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s LimitExceededException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s LimitExceededException) RequestID() string {
	return s.respMetadata.RequestID
}

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

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

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *ListTagsLogGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ListTagsLogGroupInput"}
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *ListTagsLogGroupInput) SetLogGroupName(v string) *ListTagsLogGroupInput {
	s.LogGroupName = &v
	return s
}

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

	// The tags for the log group.
	Tags map[string]*string `locationName:"tags" min:"1" type:"map"`
}

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

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

// SetTags sets the Tags field's value.
func (s *ListTagsLogGroupOutput) SetTags(v map[string]*string) *ListTagsLogGroupOutput {
	s.Tags = v
	return s
}

// Represents a log group.
type LogGroup struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the log group.
	Arn *string `locationName:"arn" type:"string"`

	// The creation time of the log group, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// The Amazon Resource Name (ARN) of the CMK to use when encrypting log data.
	KmsKeyId *string `locationName:"kmsKeyId" type:"string"`

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

	// The number of metric filters.
	MetricFilterCount *int64 `locationName:"metricFilterCount" type:"integer"`

	// The number of days to retain the 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, and 3653.
	RetentionInDays *int64 `locationName:"retentionInDays" type:"integer"`

	// The number of bytes stored.
	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()
}

// SetArn sets the Arn field's value.
func (s *LogGroup) SetArn(v string) *LogGroup {
	s.Arn = &v
	return s
}

// SetCreationTime sets the CreationTime field's value.
func (s *LogGroup) SetCreationTime(v int64) *LogGroup {
	s.CreationTime = &v
	return s
}

// SetKmsKeyId sets the KmsKeyId field's value.
func (s *LogGroup) SetKmsKeyId(v string) *LogGroup {
	s.KmsKeyId = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *LogGroup) SetLogGroupName(v string) *LogGroup {
	s.LogGroupName = &v
	return s
}

// SetMetricFilterCount sets the MetricFilterCount field's value.
func (s *LogGroup) SetMetricFilterCount(v int64) *LogGroup {
	s.MetricFilterCount = &v
	return s
}

// SetRetentionInDays sets the RetentionInDays field's value.
func (s *LogGroup) SetRetentionInDays(v int64) *LogGroup {
	s.RetentionInDays = &v
	return s
}

// SetStoredBytes sets the StoredBytes field's value.
func (s *LogGroup) SetStoredBytes(v int64) *LogGroup {
	s.StoredBytes = &v
	return s
}

// The fields contained in log events found by a GetLogGroupFields operation,
// along with the percentage of queried log events in which each field appears.
type LogGroupField struct {
	_ struct{} `type:"structure"`

	// The name of a log field.
	Name *string `locationName:"name" type:"string"`

	// The percentage of log events queried that contained the field.
	Percent *int64 `locationName:"percent" type:"integer"`
}

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

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

// SetName sets the Name field's value.
func (s *LogGroupField) SetName(v string) *LogGroupField {
	s.Name = &v
	return s
}

// SetPercent sets the Percent field's value.
func (s *LogGroupField) SetPercent(v int64) *LogGroupField {
	s.Percent = &v
	return s
}

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

	// The Amazon Resource Name (ARN) of the log stream.
	Arn *string `locationName:"arn" type:"string"`

	// The creation time of the stream, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// The time of the first event, expressed as the number of milliseconds after
	// Jan 1, 1970 00:00:00 UTC.
	FirstEventTimestamp *int64 `locationName:"firstEventTimestamp" type:"long"`

	// The time of the most recent log event in the log stream in CloudWatch Logs.
	// This number is expressed as the number of milliseconds after Jan 1, 1970
	// 00:00:00 UTC. The lastEventTime value updates on an eventual consistency
	// basis. It typically updates in less than an hour from ingestion, but may
	// take longer in some rare situations.
	LastEventTimestamp *int64 `locationName:"lastEventTimestamp" type:"long"`

	// The ingestion time, expressed as the number of milliseconds after Jan 1,
	// 1970 00:00:00 UTC.
	LastIngestionTime *int64 `locationName:"lastIngestionTime" type:"long"`

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

	// The number of bytes stored.
	//
	// IMPORTANT:On June 17, 2019, this parameter was deprecated for log streams,
	// and is always reported as zero. This change applies only to log streams.
	// The storedBytes parameter for log groups is not affected.
	//
	// Deprecated: Starting on June 17, 2019, this parameter will be deprecated for log streams, and will be reported as zero. This change applies only to log streams. The storedBytes parameter for log groups is not affected.
	StoredBytes *int64 `locationName:"storedBytes" deprecated:"true" type:"long"`

	// The sequence token.
	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()
}

// SetArn sets the Arn field's value.
func (s *LogStream) SetArn(v string) *LogStream {
	s.Arn = &v
	return s
}

// SetCreationTime sets the CreationTime field's value.
func (s *LogStream) SetCreationTime(v int64) *LogStream {
	s.CreationTime = &v
	return s
}

// SetFirstEventTimestamp sets the FirstEventTimestamp field's value.
func (s *LogStream) SetFirstEventTimestamp(v int64) *LogStream {
	s.FirstEventTimestamp = &v
	return s
}

// SetLastEventTimestamp sets the LastEventTimestamp field's value.
func (s *LogStream) SetLastEventTimestamp(v int64) *LogStream {
	s.LastEventTimestamp = &v
	return s
}

// SetLastIngestionTime sets the LastIngestionTime field's value.
func (s *LogStream) SetLastIngestionTime(v int64) *LogStream {
	s.LastIngestionTime = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *LogStream) SetLogStreamName(v string) *LogStream {
	s.LogStreamName = &v
	return s
}

// SetStoredBytes sets the StoredBytes field's value.
func (s *LogStream) SetStoredBytes(v int64) *LogStream {
	s.StoredBytes = &v
	return s
}

// SetUploadSequenceToken sets the UploadSequenceToken field's value.
func (s *LogStream) SetUploadSequenceToken(v string) *LogStream {
	s.UploadSequenceToken = &v
	return s
}

// The query string is not valid. Details about this error are displayed in
// a QueryCompileError object. For more information, see .
//
// For more information about valid query syntax, see CloudWatch Logs Insights
// Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html).
type MalformedQueryException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`

	// Reserved.
	QueryCompileError *QueryCompileError `locationName:"queryCompileError" type:"structure"`
}

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

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

func newErrorMalformedQueryException(v protocol.ResponseMetadata) error {
	return &MalformedQueryException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s MalformedQueryException) Code() string {
	return "MalformedQueryException"
}

// Message returns the exception's message.
func (s MalformedQueryException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s MalformedQueryException) OrigErr() error {
	return nil
}

func (s MalformedQueryException) Error() string {
	return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String())
}

// Status code returns the HTTP status code for the request's response error.
func (s MalformedQueryException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s MalformedQueryException) RequestID() string {
	return s.respMetadata.RequestID
}

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

	// The creation time of the metric filter, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// The name of the metric 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"`

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

	// The metric transformations.
	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()
}

// SetCreationTime sets the CreationTime field's value.
func (s *MetricFilter) SetCreationTime(v int64) *MetricFilter {
	s.CreationTime = &v
	return s
}

// SetFilterName sets the FilterName field's value.
func (s *MetricFilter) SetFilterName(v string) *MetricFilter {
	s.FilterName = &v
	return s
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *MetricFilter) SetFilterPattern(v string) *MetricFilter {
	s.FilterPattern = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *MetricFilter) SetLogGroupName(v string) *MetricFilter {
	s.LogGroupName = &v
	return s
}

// SetMetricTransformations sets the MetricTransformations field's value.
func (s *MetricFilter) SetMetricTransformations(v []*MetricTransformation) *MetricFilter {
	s.MetricTransformations = v
	return s
}

// Represents a matched event.
type MetricFilterMatchRecord struct {
	_ struct{} `type:"structure"`

	// The raw event data.
	EventMessage *string `locationName:"eventMessage" min:"1" type:"string"`

	// The event number.
	EventNumber *int64 `locationName:"eventNumber" type:"long"`

	// The values extracted from the event data by the filter.
	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()
}

// SetEventMessage sets the EventMessage field's value.
func (s *MetricFilterMatchRecord) SetEventMessage(v string) *MetricFilterMatchRecord {
	s.EventMessage = &v
	return s
}

// SetEventNumber sets the EventNumber field's value.
func (s *MetricFilterMatchRecord) SetEventNumber(v int64) *MetricFilterMatchRecord {
	s.EventNumber = &v
	return s
}

// SetExtractedValues sets the ExtractedValues field's value.
func (s *MetricFilterMatchRecord) SetExtractedValues(v map[string]*string) *MetricFilterMatchRecord {
	s.ExtractedValues = v
	return s
}

// Indicates how to transform ingested log events to metric data in a CloudWatch
// metric.
type MetricTransformation struct {
	_ struct{} `type:"structure"`

	// (Optional) The value to emit when a filter pattern does not match a log event.
	// This value can be null.
	DefaultValue *float64 `locationName:"defaultValue" type:"double"`

	// The name of the CloudWatch metric.
	//
	// MetricName is a required field
	MetricName *string `locationName:"metricName" type:"string" required:"true"`

	// The namespace of the CloudWatch metric.
	//
	// MetricNamespace is a required field
	MetricNamespace *string `locationName:"metricNamespace" type:"string" required:"true"`

	// The value to publish to the CloudWatch metric when a filter pattern matches
	// a log event.
	//
	// MetricValue is a required field
	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
}

// SetDefaultValue sets the DefaultValue field's value.
func (s *MetricTransformation) SetDefaultValue(v float64) *MetricTransformation {
	s.DefaultValue = &v
	return s
}

// SetMetricName sets the MetricName field's value.
func (s *MetricTransformation) SetMetricName(v string) *MetricTransformation {
	s.MetricName = &v
	return s
}

// SetMetricNamespace sets the MetricNamespace field's value.
func (s *MetricTransformation) SetMetricNamespace(v string) *MetricTransformation {
	s.MetricNamespace = &v
	return s
}

// SetMetricValue sets the MetricValue field's value.
func (s *MetricTransformation) SetMetricValue(v string) *MetricTransformation {
	s.MetricValue = &v
	return s
}

// Multiple requests to update the same resource were in conflict.
type OperationAbortedException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorOperationAbortedException(v protocol.ResponseMetadata) error {
	return &OperationAbortedException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s OperationAbortedException) Code() string {
	return "OperationAbortedException"
}

// Message returns the exception's message.
func (s OperationAbortedException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s OperationAbortedException) OrigErr() error {
	return nil
}

func (s OperationAbortedException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s OperationAbortedException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s OperationAbortedException) RequestID() string {
	return s.respMetadata.RequestID
}

// Represents a log event.
type OutputLogEvent struct {
	_ struct{} `type:"structure"`

	// The time the event was ingested, expressed as the number of milliseconds
	// after Jan 1, 1970 00:00:00 UTC.
	IngestionTime *int64 `locationName:"ingestionTime" type:"long"`

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

	// The time the event occurred, expressed as the number of milliseconds after
	// 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()
}

// SetIngestionTime sets the IngestionTime field's value.
func (s *OutputLogEvent) SetIngestionTime(v int64) *OutputLogEvent {
	s.IngestionTime = &v
	return s
}

// SetMessage sets the Message field's value.
func (s *OutputLogEvent) SetMessage(v string) *OutputLogEvent {
	s.Message = &v
	return s
}

// SetTimestamp sets the Timestamp field's value.
func (s *OutputLogEvent) SetTimestamp(v int64) *OutputLogEvent {
	s.Timestamp = &v
	return s
}

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

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

	// The ARN of an IAM role that grants CloudWatch Logs permissions to call the
	// Amazon Kinesis PutRecord operation on the destination stream.
	//
	// RoleArn is a required field
	RoleArn *string `locationName:"roleArn" min:"1" type:"string" required:"true"`

	// The ARN of an Amazon Kinesis stream to which to deliver matching log events.
	//
	// TargetArn is a required field
	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
}

// SetDestinationName sets the DestinationName field's value.
func (s *PutDestinationInput) SetDestinationName(v string) *PutDestinationInput {
	s.DestinationName = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *PutDestinationInput) SetRoleArn(v string) *PutDestinationInput {
	s.RoleArn = &v
	return s
}

// SetTargetArn sets the TargetArn field's value.
func (s *PutDestinationInput) SetTargetArn(v string) *PutDestinationInput {
	s.TargetArn = &v
	return s
}

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

	// The destination.
	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()
}

// SetDestination sets the Destination field's value.
func (s *PutDestinationOutput) SetDestination(v *Destination) *PutDestinationOutput {
	s.Destination = v
	return s
}

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

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

	// A name for an existing destination.
	//
	// DestinationName is a required field
	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
}

// SetAccessPolicy sets the AccessPolicy field's value.
func (s *PutDestinationPolicyInput) SetAccessPolicy(v string) *PutDestinationPolicyInput {
	s.AccessPolicy = &v
	return s
}

// SetDestinationName sets the DestinationName field's value.
func (s *PutDestinationPolicyInput) SetDestinationName(v string) *PutDestinationPolicyInput {
	s.DestinationName = &v
	return s
}

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"`

	// The log events.
	//
	// LogEvents is a required field
	LogEvents []*InputLogEvent `locationName:"logEvents" min:"1" type:"list" required:"true"`

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

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

	// The sequence token obtained from the response of the previous PutLogEvents
	// call. An upload in a newly created log stream does not require a sequence
	// token. You can also get the sequence token using DescribeLogStreams. If you
	// call PutLogEvents twice within a narrow time period using the same value
	// for sequenceToken, both calls may be successful, or one may be rejected.
	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
}

// SetLogEvents sets the LogEvents field's value.
func (s *PutLogEventsInput) SetLogEvents(v []*InputLogEvent) *PutLogEventsInput {
	s.LogEvents = v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *PutLogEventsInput) SetLogGroupName(v string) *PutLogEventsInput {
	s.LogGroupName = &v
	return s
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *PutLogEventsInput) SetLogStreamName(v string) *PutLogEventsInput {
	s.LogStreamName = &v
	return s
}

// SetSequenceToken sets the SequenceToken field's value.
func (s *PutLogEventsInput) SetSequenceToken(v string) *PutLogEventsInput {
	s.SequenceToken = &v
	return s
}

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

	// The next sequence token.
	NextSequenceToken *string `locationName:"nextSequenceToken" min:"1" type:"string"`

	// The rejected events.
	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()
}

// SetNextSequenceToken sets the NextSequenceToken field's value.
func (s *PutLogEventsOutput) SetNextSequenceToken(v string) *PutLogEventsOutput {
	s.NextSequenceToken = &v
	return s
}

// SetRejectedLogEventsInfo sets the RejectedLogEventsInfo field's value.
func (s *PutLogEventsOutput) SetRejectedLogEventsInfo(v *RejectedLogEventsInfo) *PutLogEventsOutput {
	s.RejectedLogEventsInfo = v
	return s
}

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

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

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

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

	// A collection of information that defines how metric data gets emitted.
	//
	// MetricTransformations is a required field
	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
}

// SetFilterName sets the FilterName field's value.
func (s *PutMetricFilterInput) SetFilterName(v string) *PutMetricFilterInput {
	s.FilterName = &v
	return s
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *PutMetricFilterInput) SetFilterPattern(v string) *PutMetricFilterInput {
	s.FilterPattern = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *PutMetricFilterInput) SetLogGroupName(v string) *PutMetricFilterInput {
	s.LogGroupName = &v
	return s
}

// SetMetricTransformations sets the MetricTransformations field's value.
func (s *PutMetricFilterInput) SetMetricTransformations(v []*MetricTransformation) *PutMetricFilterInput {
	s.MetricTransformations = v
	return s
}

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 PutResourcePolicyInput struct {
	_ struct{} `type:"structure"`

	// Details of the new policy, including the identity of the principal that is
	// enabled to put logs to this account. This is formatted as a JSON string.
	// This parameter is required.
	//
	// The following example creates a resource policy enabling the Route 53 service
	// to put DNS query logs in to the specified log group. Replace "logArn" with
	// the ARN of your CloudWatch Logs resource, such as a log group or log stream.
	//
	// { "Version": "2012-10-17", "Statement": [ { "Sid": "Route53LogsToCloudWatchLogs",
	// "Effect": "Allow", "Principal": { "Service": [ "route53.amazonaws.com" ]
	// }, "Action":"logs:PutLogEvents", "Resource": "logArn" } ] }
	PolicyDocument *string `locationName:"policyDocument" min:"1" type:"string"`

	// Name of the new policy. This parameter is required.
	PolicyName *string `locationName:"policyName" type:"string"`
}

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

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

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

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

// SetPolicyDocument sets the PolicyDocument field's value.
func (s *PutResourcePolicyInput) SetPolicyDocument(v string) *PutResourcePolicyInput {
	s.PolicyDocument = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *PutResourcePolicyInput) SetPolicyName(v string) *PutResourcePolicyInput {
	s.PolicyName = &v
	return s
}

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

	// The new policy.
	ResourcePolicy *ResourcePolicy `locationName:"resourcePolicy" type:"structure"`
}

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

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

// SetResourcePolicy sets the ResourcePolicy field's value.
func (s *PutResourcePolicyOutput) SetResourcePolicy(v *ResourcePolicy) *PutResourcePolicyOutput {
	s.ResourcePolicy = v
	return s
}

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

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

	// The number of days to retain the 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, and 3653.
	//
	// RetentionInDays is a required field
	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
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *PutRetentionPolicyInput) SetLogGroupName(v string) *PutRetentionPolicyInput {
	s.LogGroupName = &v
	return s
}

// SetRetentionInDays sets the RetentionInDays field's value.
func (s *PutRetentionPolicyInput) SetRetentionInDays(v int64) *PutRetentionPolicyInput {
	s.RetentionInDays = &v
	return s
}

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 (specified using an ARN) belonging to a different
	//    account, for cross-account delivery.
	//
	//    * An Amazon Kinesis Firehose delivery 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 is a required field
	DestinationArn *string `locationName:"destinationArn" min:"1" type:"string" required:"true"`

	// The method used to distribute log data to the destination. By default log
	// data is grouped by log stream, but the grouping can be set to random for
	// a more even distribution. This property is only applicable when the destination
	// is an Amazon Kinesis stream.
	Distribution *string `locationName:"distribution" type:"string" enum:"Distribution"`

	// A name for the subscription filter. If you are updating an existing filter,
	// you must specify the correct name in filterName. Otherwise, the call fails
	// because you cannot associate a second filter with a log group. To find the
	// name of the filter currently associated with a log group, use DescribeSubscriptionFilters.
	//
	// FilterName is a required field
	FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"`

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

	// The name of the log group.
	//
	// LogGroupName is a required field
	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 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
}

// SetDestinationArn sets the DestinationArn field's value.
func (s *PutSubscriptionFilterInput) SetDestinationArn(v string) *PutSubscriptionFilterInput {
	s.DestinationArn = &v
	return s
}

// SetDistribution sets the Distribution field's value.
func (s *PutSubscriptionFilterInput) SetDistribution(v string) *PutSubscriptionFilterInput {
	s.Distribution = &v
	return s
}

// SetFilterName sets the FilterName field's value.
func (s *PutSubscriptionFilterInput) SetFilterName(v string) *PutSubscriptionFilterInput {
	s.FilterName = &v
	return s
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *PutSubscriptionFilterInput) SetFilterPattern(v string) *PutSubscriptionFilterInput {
	s.FilterPattern = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *PutSubscriptionFilterInput) SetLogGroupName(v string) *PutSubscriptionFilterInput {
	s.LogGroupName = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *PutSubscriptionFilterInput) SetRoleArn(v string) *PutSubscriptionFilterInput {
	s.RoleArn = &v
	return s
}

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()
}

// Reserved.
type QueryCompileError struct {
	_ struct{} `type:"structure"`

	// Reserved.
	Location *QueryCompileErrorLocation `locationName:"location" type:"structure"`

	// Reserved.
	Message *string `locationName:"message" type:"string"`
}

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

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

// SetLocation sets the Location field's value.
func (s *QueryCompileError) SetLocation(v *QueryCompileErrorLocation) *QueryCompileError {
	s.Location = v
	return s
}

// SetMessage sets the Message field's value.
func (s *QueryCompileError) SetMessage(v string) *QueryCompileError {
	s.Message = &v
	return s
}

// Reserved.
type QueryCompileErrorLocation struct {
	_ struct{} `type:"structure"`

	// Reserved.
	EndCharOffset *int64 `locationName:"endCharOffset" type:"integer"`

	// Reserved.
	StartCharOffset *int64 `locationName:"startCharOffset" type:"integer"`
}

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

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

// SetEndCharOffset sets the EndCharOffset field's value.
func (s *QueryCompileErrorLocation) SetEndCharOffset(v int64) *QueryCompileErrorLocation {
	s.EndCharOffset = &v
	return s
}

// SetStartCharOffset sets the StartCharOffset field's value.
func (s *QueryCompileErrorLocation) SetStartCharOffset(v int64) *QueryCompileErrorLocation {
	s.StartCharOffset = &v
	return s
}

// Information about one CloudWatch Logs Insights query that matches the request
// in a DescribeQueries operation.
type QueryInfo struct {
	_ struct{} `type:"structure"`

	// The date and time that this query was created.
	CreateTime *int64 `locationName:"createTime" type:"long"`

	// The name of the log group scanned by this query.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	// The unique ID number of this query.
	QueryId *string `locationName:"queryId" type:"string"`

	// The query string used in this query.
	QueryString *string `locationName:"queryString" type:"string"`

	// The status of this query. Possible values are Cancelled, Complete, Failed,
	// Running, Scheduled, and Unknown.
	Status *string `locationName:"status" type:"string" enum:"QueryStatus"`
}

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

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

// SetCreateTime sets the CreateTime field's value.
func (s *QueryInfo) SetCreateTime(v int64) *QueryInfo {
	s.CreateTime = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *QueryInfo) SetLogGroupName(v string) *QueryInfo {
	s.LogGroupName = &v
	return s
}

// SetQueryId sets the QueryId field's value.
func (s *QueryInfo) SetQueryId(v string) *QueryInfo {
	s.QueryId = &v
	return s
}

// SetQueryString sets the QueryString field's value.
func (s *QueryInfo) SetQueryString(v string) *QueryInfo {
	s.QueryString = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *QueryInfo) SetStatus(v string) *QueryInfo {
	s.Status = &v
	return s
}

// Contains the number of log events scanned by the query, the number of log
// events that matched the query criteria, and the total number of bytes in
// the log events that were scanned.
type QueryStatistics struct {
	_ struct{} `type:"structure"`

	// The total number of bytes in the log events scanned during the query.
	BytesScanned *float64 `locationName:"bytesScanned" type:"double"`

	// The number of log events that matched the query string.
	RecordsMatched *float64 `locationName:"recordsMatched" type:"double"`

	// The total number of log events scanned during the query.
	RecordsScanned *float64 `locationName:"recordsScanned" type:"double"`
}

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

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

// SetBytesScanned sets the BytesScanned field's value.
func (s *QueryStatistics) SetBytesScanned(v float64) *QueryStatistics {
	s.BytesScanned = &v
	return s
}

// SetRecordsMatched sets the RecordsMatched field's value.
func (s *QueryStatistics) SetRecordsMatched(v float64) *QueryStatistics {
	s.RecordsMatched = &v
	return s
}

// SetRecordsScanned sets the RecordsScanned field's value.
func (s *QueryStatistics) SetRecordsScanned(v float64) *QueryStatistics {
	s.RecordsScanned = &v
	return s
}

// Represents the rejected events.
type RejectedLogEventsInfo struct {
	_ struct{} `type:"structure"`

	// The expired log events.
	ExpiredLogEventEndIndex *int64 `locationName:"expiredLogEventEndIndex" type:"integer"`

	// The log events that are too new.
	TooNewLogEventStartIndex *int64 `locationName:"tooNewLogEventStartIndex" type:"integer"`

	// The log events that are too old.
	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()
}

// SetExpiredLogEventEndIndex sets the ExpiredLogEventEndIndex field's value.
func (s *RejectedLogEventsInfo) SetExpiredLogEventEndIndex(v int64) *RejectedLogEventsInfo {
	s.ExpiredLogEventEndIndex = &v
	return s
}

// SetTooNewLogEventStartIndex sets the TooNewLogEventStartIndex field's value.
func (s *RejectedLogEventsInfo) SetTooNewLogEventStartIndex(v int64) *RejectedLogEventsInfo {
	s.TooNewLogEventStartIndex = &v
	return s
}

// SetTooOldLogEventEndIndex sets the TooOldLogEventEndIndex field's value.
func (s *RejectedLogEventsInfo) SetTooOldLogEventEndIndex(v int64) *RejectedLogEventsInfo {
	s.TooOldLogEventEndIndex = &v
	return s
}

// The specified resource already exists.
type ResourceAlreadyExistsException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorResourceAlreadyExistsException(v protocol.ResponseMetadata) error {
	return &ResourceAlreadyExistsException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s ResourceAlreadyExistsException) Code() string {
	return "ResourceAlreadyExistsException"
}

// Message returns the exception's message.
func (s ResourceAlreadyExistsException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s ResourceAlreadyExistsException) OrigErr() error {
	return nil
}

func (s ResourceAlreadyExistsException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s ResourceAlreadyExistsException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s ResourceAlreadyExistsException) RequestID() string {
	return s.respMetadata.RequestID
}

// The specified resource does not exist.
type ResourceNotFoundException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorResourceNotFoundException(v protocol.ResponseMetadata) error {
	return &ResourceNotFoundException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s ResourceNotFoundException) Code() string {
	return "ResourceNotFoundException"
}

// Message returns the exception's message.
func (s ResourceNotFoundException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s ResourceNotFoundException) OrigErr() error {
	return nil
}

func (s ResourceNotFoundException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s ResourceNotFoundException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s ResourceNotFoundException) RequestID() string {
	return s.respMetadata.RequestID
}

// A policy enabling one or more entities to put logs to a log group in this
// account.
type ResourcePolicy struct {
	_ struct{} `type:"structure"`

	// Timestamp showing when this policy was last updated, expressed as the number
	// of milliseconds after Jan 1, 1970 00:00:00 UTC.
	LastUpdatedTime *int64 `locationName:"lastUpdatedTime" type:"long"`

	// The details of the policy.
	PolicyDocument *string `locationName:"policyDocument" min:"1" type:"string"`

	// The name of the resource policy.
	PolicyName *string `locationName:"policyName" type:"string"`
}

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

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

// SetLastUpdatedTime sets the LastUpdatedTime field's value.
func (s *ResourcePolicy) SetLastUpdatedTime(v int64) *ResourcePolicy {
	s.LastUpdatedTime = &v
	return s
}

// SetPolicyDocument sets the PolicyDocument field's value.
func (s *ResourcePolicy) SetPolicyDocument(v string) *ResourcePolicy {
	s.PolicyDocument = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *ResourcePolicy) SetPolicyName(v string) *ResourcePolicy {
	s.PolicyName = &v
	return s
}

// Contains one field from one log event returned by a CloudWatch Logs Insights
// query, along with the value of that field.
type ResultField struct {
	_ struct{} `type:"structure"`

	// The log event field.
	Field *string `locationName:"field" type:"string"`

	// The value of this field.
	Value *string `locationName:"value" type:"string"`
}

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

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

// SetField sets the Field field's value.
func (s *ResultField) SetField(v string) *ResultField {
	s.Field = &v
	return s
}

// SetValue sets the Value field's value.
func (s *ResultField) SetValue(v string) *ResultField {
	s.Value = &v
	return s
}

// Represents the search status of a log stream.
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.
	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()
}

// SetLogStreamName sets the LogStreamName field's value.
func (s *SearchedLogStream) SetLogStreamName(v string) *SearchedLogStream {
	s.LogStreamName = &v
	return s
}

// SetSearchedCompletely sets the SearchedCompletely field's value.
func (s *SearchedLogStream) SetSearchedCompletely(v bool) *SearchedLogStream {
	s.SearchedCompletely = &v
	return s
}

// The service cannot complete the request.
type ServiceUnavailableException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorServiceUnavailableException(v protocol.ResponseMetadata) error {
	return &ServiceUnavailableException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s ServiceUnavailableException) Code() string {
	return "ServiceUnavailableException"
}

// Message returns the exception's message.
func (s ServiceUnavailableException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s ServiceUnavailableException) OrigErr() error {
	return nil
}

func (s ServiceUnavailableException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s ServiceUnavailableException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s ServiceUnavailableException) RequestID() string {
	return s.respMetadata.RequestID
}

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

	// The end of the time range to query. The range is inclusive, so the specified
	// end time is included in the query. Specified as epoch time, the number of
	// seconds since January 1, 1970, 00:00:00 UTC.
	//
	// EndTime is a required field
	EndTime *int64 `locationName:"endTime" type:"long" required:"true"`

	// The maximum number of log events to return in the query. If the query string
	// uses the fields command, only the specified fields and their values are returned.
	// The default is 1000.
	Limit *int64 `locationName:"limit" min:"1" type:"integer"`

	// The log group on which to perform the query.
	//
	// A StartQuery operation must include a logGroupNames or a logGroupName parameter,
	// but not both.
	LogGroupName *string `locationName:"logGroupName" min:"1" type:"string"`

	// The list of log groups to be queried. You can include up to 20 log groups.
	//
	// A StartQuery operation must include a logGroupNames or a logGroupName parameter,
	// but not both.
	LogGroupNames []*string `locationName:"logGroupNames" type:"list"`

	// The query string to use. For more information, see CloudWatch Logs Insights
	// Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html).
	//
	// QueryString is a required field
	QueryString *string `locationName:"queryString" type:"string" required:"true"`

	// The beginning of the time range to query. The range is inclusive, so the
	// specified start time is included in the query. Specified as epoch time, the
	// number of seconds since January 1, 1970, 00:00:00 UTC.
	//
	// StartTime is a required field
	StartTime *int64 `locationName:"startTime" type:"long" required:"true"`
}

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

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

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

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

// SetEndTime sets the EndTime field's value.
func (s *StartQueryInput) SetEndTime(v int64) *StartQueryInput {
	s.EndTime = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *StartQueryInput) SetLimit(v int64) *StartQueryInput {
	s.Limit = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *StartQueryInput) SetLogGroupName(v string) *StartQueryInput {
	s.LogGroupName = &v
	return s
}

// SetLogGroupNames sets the LogGroupNames field's value.
func (s *StartQueryInput) SetLogGroupNames(v []*string) *StartQueryInput {
	s.LogGroupNames = v
	return s
}

// SetQueryString sets the QueryString field's value.
func (s *StartQueryInput) SetQueryString(v string) *StartQueryInput {
	s.QueryString = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *StartQueryInput) SetStartTime(v int64) *StartQueryInput {
	s.StartTime = &v
	return s
}

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

	// The unique ID of the query.
	QueryId *string `locationName:"queryId" type:"string"`
}

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

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

// SetQueryId sets the QueryId field's value.
func (s *StartQueryOutput) SetQueryId(v string) *StartQueryOutput {
	s.QueryId = &v
	return s
}

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

	// The ID number of the query to stop. If necessary, you can use DescribeQueries
	// to find this ID number.
	//
	// QueryId is a required field
	QueryId *string `locationName:"queryId" type:"string" required:"true"`
}

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

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

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

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

// SetQueryId sets the QueryId field's value.
func (s *StopQueryInput) SetQueryId(v string) *StopQueryInput {
	s.QueryId = &v
	return s
}

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

	// This is true if the query was stopped by the StopQuery operation.
	Success *bool `locationName:"success" type:"boolean"`
}

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

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

// SetSuccess sets the Success field's value.
func (s *StopQueryOutput) SetSuccess(v bool) *StopQueryOutput {
	s.Success = &v
	return s
}

// Represents a subscription filter.
type SubscriptionFilter struct {
	_ struct{} `type:"structure"`

	// The creation time of the subscription filter, expressed as the number of
	// milliseconds after Jan 1, 1970 00:00:00 UTC.
	CreationTime *int64 `locationName:"creationTime" type:"long"`

	// The Amazon Resource Name (ARN) of the destination.
	DestinationArn *string `locationName:"destinationArn" min:"1" type:"string"`

	// The method used to distribute log data to the destination, which can be either
	// random or grouped by log stream.
	Distribution *string `locationName:"distribution" type:"string" enum:"Distribution"`

	// The name of the 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"`

	// The name of the log group.
	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()
}

// SetCreationTime sets the CreationTime field's value.
func (s *SubscriptionFilter) SetCreationTime(v int64) *SubscriptionFilter {
	s.CreationTime = &v
	return s
}

// SetDestinationArn sets the DestinationArn field's value.
func (s *SubscriptionFilter) SetDestinationArn(v string) *SubscriptionFilter {
	s.DestinationArn = &v
	return s
}

// SetDistribution sets the Distribution field's value.
func (s *SubscriptionFilter) SetDistribution(v string) *SubscriptionFilter {
	s.Distribution = &v
	return s
}

// SetFilterName sets the FilterName field's value.
func (s *SubscriptionFilter) SetFilterName(v string) *SubscriptionFilter {
	s.FilterName = &v
	return s
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *SubscriptionFilter) SetFilterPattern(v string) *SubscriptionFilter {
	s.FilterPattern = &v
	return s
}

// SetLogGroupName sets the LogGroupName field's value.
func (s *SubscriptionFilter) SetLogGroupName(v string) *SubscriptionFilter {
	s.LogGroupName = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *SubscriptionFilter) SetRoleArn(v string) *SubscriptionFilter {
	s.RoleArn = &v
	return s
}

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

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

	// The key-value pairs to use for the tags.
	//
	// Tags is a required field
	Tags map[string]*string `locationName:"tags" min:"1" type:"map" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *TagLogGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TagLogGroupInput"}
	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.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}

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

// SetLogGroupName sets the LogGroupName field's value.
func (s *TagLogGroupInput) SetLogGroupName(v string) *TagLogGroupInput {
	s.LogGroupName = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *TagLogGroupInput) SetTags(v map[string]*string) *TagLogGroupInput {
	s.Tags = v
	return s
}

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

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

// GoString returns the string representation
func (s TagLogGroupOutput) 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 is a required field
	FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"`

	// The log event messages to test.
	//
	// LogEventMessages is a required field
	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
}

// SetFilterPattern sets the FilterPattern field's value.
func (s *TestMetricFilterInput) SetFilterPattern(v string) *TestMetricFilterInput {
	s.FilterPattern = &v
	return s
}

// SetLogEventMessages sets the LogEventMessages field's value.
func (s *TestMetricFilterInput) SetLogEventMessages(v []*string) *TestMetricFilterInput {
	s.LogEventMessages = v
	return s
}

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

	// The matched events.
	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()
}

// SetMatches sets the Matches field's value.
func (s *TestMetricFilterOutput) SetMatches(v []*MetricFilterMatchRecord) *TestMetricFilterOutput {
	s.Matches = v
	return s
}

// The most likely cause is an invalid AWS access key ID or secret key.
type UnrecognizedClientException struct {
	_            struct{} `type:"structure"`
	respMetadata protocol.ResponseMetadata

	Message_ *string `locationName:"message" type:"string"`
}

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

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

func newErrorUnrecognizedClientException(v protocol.ResponseMetadata) error {
	return &UnrecognizedClientException{
		respMetadata: v,
	}
}

// Code returns the exception type name.
func (s UnrecognizedClientException) Code() string {
	return "UnrecognizedClientException"
}

// Message returns the exception's message.
func (s UnrecognizedClientException) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s UnrecognizedClientException) OrigErr() error {
	return nil
}

func (s UnrecognizedClientException) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s UnrecognizedClientException) StatusCode() int {
	return s.respMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s UnrecognizedClientException) RequestID() string {
	return s.respMetadata.RequestID
}

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

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

	// The tag keys. The corresponding tags are removed from the log group.
	//
	// Tags is a required field
	Tags []*string `locationName:"tags" min:"1" type:"list" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *UntagLogGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "UntagLogGroupInput"}
	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.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}

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

// SetLogGroupName sets the LogGroupName field's value.
func (s *UntagLogGroupInput) SetLogGroupName(v string) *UntagLogGroupInput {
	s.LogGroupName = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *UntagLogGroupInput) SetTags(v []*string) *UntagLogGroupInput {
	s.Tags = v
	return s
}

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

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

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

// The method used to distribute log data to the destination, which can be either
// random or grouped by log stream.
const (
	// DistributionRandom is a Distribution enum value
	DistributionRandom = "Random"

	// DistributionByLogStream is a Distribution enum value
	DistributionByLogStream = "ByLogStream"
)

const (
	// ExportTaskStatusCodeCancelled is a ExportTaskStatusCode enum value
	ExportTaskStatusCodeCancelled = "CANCELLED"

	// ExportTaskStatusCodeCompleted is a ExportTaskStatusCode enum value
	ExportTaskStatusCodeCompleted = "COMPLETED"

	// ExportTaskStatusCodeFailed is a ExportTaskStatusCode enum value
	ExportTaskStatusCodeFailed = "FAILED"

	// ExportTaskStatusCodePending is a ExportTaskStatusCode enum value
	ExportTaskStatusCodePending = "PENDING"

	// ExportTaskStatusCodePendingCancel is a ExportTaskStatusCode enum value
	ExportTaskStatusCodePendingCancel = "PENDING_CANCEL"

	// ExportTaskStatusCodeRunning is a ExportTaskStatusCode enum value
	ExportTaskStatusCodeRunning = "RUNNING"
)

const (
	// OrderByLogStreamName is a OrderBy enum value
	OrderByLogStreamName = "LogStreamName"

	// OrderByLastEventTime is a OrderBy enum value
	OrderByLastEventTime = "LastEventTime"
)

const (
	// QueryStatusScheduled is a QueryStatus enum value
	QueryStatusScheduled = "Scheduled"

	// QueryStatusRunning is a QueryStatus enum value
	QueryStatusRunning = "Running"

	// QueryStatusComplete is a QueryStatus enum value
	QueryStatusComplete = "Complete"

	// QueryStatusFailed is a QueryStatus enum value
	QueryStatusFailed = "Failed"

	// QueryStatusCancelled is a QueryStatus enum value
	QueryStatusCancelled = "Cancelled"
)
