The Amplify Logger enables you to troubleshoot and debug issues with your apps, to help you provide the best experience for your customers. You can log messages for errors by the Amplify library and add custom logs as well and send them to Amazon CloudWatch. With the Amplify Logger, you also can remotely change your logging configuration to adjust your logging levels, or add an allow list of customer IDs to help you detect issues more granularly for your apps in production.

## Prerequisites

import iosPreReq from '/src/fragments/lib/logging/ios/setup_logging/10_pre_req.mdx';
import androidPreReq from '/src/fragments/lib/logging/android/setup_logging/10_pre_req.mdx';

<Fragments
  fragments={{
    ios: iosPreReq,
    android: androidPreReq
  }}
/>

## Provision backend resources

<Callout>

You can use the Amplify CLI to [add custom CDK resources](https://docs.amplify.aws/cli/custom/cdk/).  

</Callout>

You will need to create a log group in Amazon CloudWatch to send logs to.  You can create and provision a log group by going through the AWS Console and creating your log group manually or using Amplify CLI and AWS CDK to provision and deploy the AWS resources.

Below is a sample CDK construct to create the Amazon CloudWatch log group as well as creating and assigning the permission policies to Amplify roles.

The `<log-group-name>` and `<region>` configured in the CDK construct will be used later to initialize the Amplify Logger plugin.

### Replace the placeholder values with your own values:
* `<log-group-name>` is the log group that logs will be sent to.  Note that this CDK construct sample includes logic to create the CloudWatch log group that you may have already created in previous steps.
* `<amplify-authenticated-role-name>` and `<amplify-unauthenticated-role-name>` are Amplify roles created as part of Amplify Auth configuration via Amplify CLI.  

```ts
import * as cdk from "aws-cdk-lib"
import { Construct } from "constructs"
import * as logs from "aws-cdk-lib/aws-logs"
import * as path from "path"
import * as iam from "aws-cdk-lib/aws-iam"

export class RemoteLoggingConstraintsConstruct extends Construct {
  constructor(scope: Construct, id: string, props: RemoteLoggingConstraintProps) {
    super(scope, id)

    const region = cdk.Stack.of(this).region
    const account = cdk.Stack.of(this).account
    const logGroupName = <log-group-name>
    const authRoleName = <amplify-authenticated-role-name> 
    const unAuthRoleName = <amplify-unauthenticated-role-name>

    new logs.LogGroup(this, 'Log Group', {
      logGroupName: logGroupName,
      retention: logs.RetentionDays.INFINITE
    })
    
    const authRole = iam.Role.fromRoleName(this, "Auth-Role", authRoleName)
    const unAuthRole = iam.Role.fromRoleName(this, "UnAuth-Role", unAuthRoleName)
    const logResource = `arn:aws:logs:${region}:${account}:log-group:${logGroupName}:log-stream:*`
    const logIAMPolicy = new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      resources: [logResource],
      actions: ["logs:PutLogEvents", "logs:DescribeLogStreams", "logs:CreateLogStream"]
    })

    authRole.addToPrincipalPolicy(logIAMPolicy)
    unAuthRole.addToPrincipalPolicy(logIAMPolicy)

    new cdk.CfnOutput(this, 'CloudWatchLogGroupName', { value: logGroupName });
    new cdk.CfnOutput(this, 'CloudWatchRegion', { value: region });
  }
}
```

The `<log-group-name>` and `<region>` will be printed out in the in the terminal.  You can use this information to setup the Amplify library in the next section.

## Initialize Amplify Logging
In this section, we will initialize and setup the Amplify library.  The Logger can be configured via a configuration file or in code when your app is initializing.

import iosInitWithConfig from '/src/fragments/lib/logging/ios/setup_logging/20_initialize_with_config.mdx';
import androidInitWithConfig from '/src/fragments/lib/logging/android/setup_logging/20_initialize_with_config.mdx';

import iosInitWithoutConfig from '/src/fragments/lib/logging/ios/setup_logging/30_initialize_without_config.mdx';
import androidInitWithoutConfig from '/src/fragments/lib/logging/android/setup_logging/30_initialize_without_config.mdx';


<BlockSwitcher>
  <Block name="With Configuration File">
    <Fragments
      fragments={{
        ios: iosInitWithConfig,
        android: androidInitWithConfig
      }}
    />
  </Block>

  <Block name="With Code">
    <Fragments
      fragments={{
        ios: iosInitWithoutConfig,
        android: androidInitWithoutConfig
      }}
    />
  </Block>

</BlockSwitcher>