CtrlK
BlogDocsLog inGet started
Tessl Logo

giuseppe-trisciuoglio/developer-kit

Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.

89

Quality

89%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

Overview
Quality
Evals
Security
Files

logs.mdplugins/developer-kit-aws/skills/aws-cloudformation/aws-cloudformation-cloudwatch/references/

CloudWatch Logs Configuration

Log Group Configurations

Basic Log Group

AWSTemplateFormatVersion: 2010-09-09
Description: CloudWatch log groups configuration

Parameters:
  LogRetentionDays:
    Type: Number
    Default: 30
    AllowedValues:
      - 1          # 1 day
      - 3          # 3 days
      - 5          # 5 days
      - 7          # 1 week
      - 14         # 2 weeks
      - 30         # 1 month
      - 60         # 2 months
      - 90         # 3 months
      - 120        # 4 months
      - 150        # 5 months
      - 180        # 6 months
      - 365        # 1 year
      - 400        # 400 days
      - 545        # 18 months
      - 731        # 2 years
      - 1095       # 3 years
      - 1827       # 5 years
      - 2190       # 6 years
      - 2555       # 7 years
      - 2922       # 8 years
      - 3285       # 9 years
      - 3650       # 10 years

Resources:
  # Application log group
  ApplicationLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/applications/${Environment}/${ApplicationName}"
      RetentionInDays: !Ref LogRetentionDays
      KmsKeyId: !Ref LogKmsKeyArn
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Application
          Value: !Ref ApplicationName
        - Key: Service
          Value: !Ref ServiceName

  # Lambda log group
  LambdaLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${LambdaFunctionName}"
      RetentionInDays: !Ref LogRetentionDays
      KmsKeyId: !Ref LogKmsKeyArn

  # Audit log group with longer retention
  AuditLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/audit/${Environment}/${ApplicationName}"
      RetentionInDays: 365
      KmsKeyId: !Ref LogKmsKeyArn

Metric Filters

Error Metric Filter

Resources:
  # Metric filter for errors
  ErrorMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: '[level="ERROR", msg]'
      LogGroupName: !Ref ApplicationLogGroup
      MetricTransformations:
        - MetricValue: "1"
          MetricNamespace: !Sub "${AWS::StackName}/Application"
          MetricName: ErrorCount
          Unit: Count
        - MetricValue: "$level"
          MetricNamespace: !Sub "${AWS::StackName}/Application"
          MetricName: LogLevel

  # Metric filter for warnings
  WarningMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: '[level="WARN", msg]'
      LogGroupName: !Ref ApplicationLogGroup
      MetricTransformations:
        - MetricValue: "1"
          MetricNamespace: !Sub "${AWS::StackName}/Application"
          MetricName: WarningCount
          Unit: Count

  # Metric filter for HTTP status codes
  HttpStatusFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: '[..., http_status > 400]'
      LogGroupName: !Ref ApplicationLogGroup
      MetricTransformations:
        - MetricValue: "1"
          MetricNamespace: !Sub "${AWS::StackName}/HTTP"
          MetricName: HttpErrorCount
          Unit: Count

  # Metric filter for latency
  LatencyMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      FilterPattern: '[..., latency=duration]'
      LogGroupName: !Ref ApplicationLogGroup
      MetricTransformations:
        - MetricValue: "$latency"
          MetricNamespace: !Sub "${AWS::StackName}/Latency"
          MetricName: AverageLatency
          Unit: Milliseconds

Subscription Filters

Subscription to Lambda

Resources:
  LogSubscriptionFilter:
    Type: AWS::Logs::SubscriptionFilter
    Properties:
      DestinationArn: !GetAtt LogProcessingFunction.Arn
      FilterPattern: '[timestamp=*Z, request_id, level, message]'
      LogGroupName: !Ref ApplicationLogGroup
      RoleArn: !GetAtt LogSubscriptionRole.Arn

  # Lambda function for log processing
  LogProcessingFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-log-processor"
      Runtime: nodejs20.x
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            event.records.forEach(record => {
              const payload = Buffer.from(record.data, 'base64').toString('utf-8');
              // Process log data
            });
          };

  # IAM role for subscription
  LogSubscriptionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: !Sub "logs.${AWS::Region}.amazonaws.com"
            Action: sts:AssumeRole
      Policies:
        - PolicyName: LambdaInvocation
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: !GetAtt LogProcessingFunction.Arn

Subscription to Kinesis Data Firehose

Resources:
  LogSubscriptionFirehose:
    Type: AWS::Logs::SubscriptionFilter
    Properties:
      DestinationArn: !GetAtt DeliveryStream.Arn
      FilterPattern: ''
      LogGroupName: !Ref ApplicationLogGroup
      RoleArn: !Ref LogSubscriptionRole

  # Kinesis Data Firehose delivery stream
  DeliveryStream:
    Type: AWS::KinesisFirehose::DeliveryStream
    Properties:
      DeliveryStreamName: !Sub "${AWS::StackName}-logs"
      DeliveryStreamType: DirectPut
      ExtendedS3DestinationConfiguration:
        BucketARN: !GetAtt LogsBucket.Arn
        BufferingHints:
          IntervalInSeconds: 300
          SizeInMBs: 5
        CompressionFormat: UNCOMPRESSED
        Prefix: logs/
        RoleARN: !GetAtt FirehoseRole.Arn

  LogsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${AWS::StackName}-logs-${AWS::AccountId}-${AWS::Region}"

  FirehoseRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: firehose.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSKinesisFirehoseServiceRole

Cross-Account Log Aggregation

Resources:
  # Central log aggregation destination
  CentralLogDestination:
    Type: AWS::Logs::Destination
    Properties:
      DestinationName: !Sub "${AWS::StackName}-central-logs"
      RoleArn: !Ref DestinationRole
      TargetArn: !GetAtt CentralKinesisStream.Arn
      Tags:
        - Key: Purpose
          Value: LogAggregation

  # Destination policy
  DestinationPolicy:
    Type: AWS::Logs::DestinationPolicy
    Properties:
      DestinationName: !Ref CentralLogDestination
      AccessPolicy: !Sub |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::${SourceAccountId}:root"
              },
              "Action": "logs:PutSubscriptionFilter",
              "Resource": !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:destination:${CentralLogDestination}"
            }
          ]
        }

  # Source account subscription
  SourceAccountSubscription:
    Type: AWS::Logs::SubscriptionFilter
    Properties:
      DestinationArn: !Sub "arn:aws:logs:${DestinationRegion}:${DestinationAccountId}:destination:${CentralLogDestinationName}"
      FilterPattern: '[timestamp, request_id, level, message]'
      LogGroupName: !Ref ApplicationLogGroup
      RoleArn: !Ref SourceSubscriptionRole

Log Insights Queries

Saved Query Definitions

Resources:
  # Query definition for recent errors
  RecentErrorsQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: !Sub "${AWS::StackName}-recent-errors"
      LogGroupNames:
        - !Ref ApplicationLogGroup
      QueryString: |
        fields @timestamp, @message
        | sort @timestamp desc
        | limit 100
        | filter @message like /ERROR/
        | display @timestamp, @message, @logStream

  # Query for performance analysis
  PerformanceQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: !Sub "${AWS::StackName}-performance"
      LogGroupNames:
        - !Ref ApplicationLogGroup
      QueryString: |
        fields @timestamp, @message, @duration
        | filter @duration > 1000
        | sort @duration desc
        | limit 50
        | display @timestamp, @duration, @message

  # Query for statistics
  StatisticsQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: !Sub "${AWS::StackName}-stats"
      LogGroupNames:
        - !Ref ApplicationLogGroup
      QueryString: |
        stats count(*) as requestCount,
              avg(@duration) as avgDuration,
              max(@duration) as maxDuration
        | filter @message like /REQUEST/
        | sort requestCount desc

Log Resource Policies

Cross-Account Log Access

Resources:
  LogGroupPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: !Sub "${AWS::StackName}-log-policy"
      PolicyDocument: !Sub |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "es.amazonaws.com"
              },
              "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream"
              ],
              "Resource": !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:${ApplicationLogGroup}*"
            }
          ]
        }

S3 Bucket Access for Logs

Resources:
  S3AccessPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyName: s3-access-policy
      PolicyDocument: !Sub |
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "delivery.logs.amazonaws.com"
              },
              "Action": "s3:PutObject",
              "Resource": !Sub "${LogsBucket.Arn}/*"
            }
          ]
        }

Export and Archive Tasks

Export Task to S3

Resources:
  LogExportTask:
    Type: Custom::LogExportTask
    Properties:
      ServiceToken: !GetAtt ExportFunction.Arn
      LogGroupName: !Ref ApplicationLogGroup
      DestinationBucket: !Ref ArchiveBucket
      DestinationPrefix: !Sub "logs/${ApplicationLogGroup}/"
      From: !Ref ExportStartTime
      To: !Ref ExportEndTime

  ExportFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs20.x
      Handler: index.handler
      Timeout: 300
      Code:
        ZipFile: |
          const AWS = require('aws-sdk');
          const logs = new AWS.CloudWatchLogs();

          exports.handler = async (event) => {
            await logs.createExportTask({
              logGroupName: event.LogGroupName,
              from: event.From,
              to: event.To,
              destination: event.DestinationBucket,
              destinationPrefix: event.DestinationPrefix
            }).promise();
          };

Log Stream Configuration

Resources:
  ApplicationLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/applications/${ApplicationName}"

  # Log stream (created automatically by application)
  # This is for reference - log streams are typically created by the logging library

CloudWatch Logs Agent

EC2 Instance with CloudWatch Agent

Resources:
  # IAM role for CloudWatch agent
  CloudWatchAgentRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref CloudWatchAgentRole

  # EC2 instance with agent
  ApplicationInstance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum install -y amazon-cloudwatch-agent
          /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
            -a fetch-config \
            -m ec2 \
            -s \
            -c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json

CloudWatch Agent Configuration

Resources:
  CloudWatchAgentConfigParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: !Sub "/aws/AmazonCloudWatchAgent/${AWS::StackName}"
      Type: String
      Value: !Sub |
        {
          "agent": {
            "metrics_collection_interval": 60,
            "run_as_user": "root"
          },
          "logs": {
            "logs_collected": {
              "files": {
                "collect_list": [
                  {
                    "file_path": "/var/log/application/app.log",
                    "log_group_name": "/aws/applications/${ApplicationName}",
                    "log_stream_name": "{instance_id}"
                  }
                ]
              }
            }
          },
          "metrics": {
            "namespace": "${ApplicationName}",
            "metrics_collected": {
              "cpu": {
                "measurement": ["cpu_usage_active"]
              },
              "mem": {
                "measurement": ["mem_used_percent"]
              },
              "disk": {
                "measurement": ["disk_used_percent"]
              }
            }
          }
        }

Log Encryption

KMS Encryption for Logs

Resources:
  # KMS key for log encryption
  LogEncryptionKey:
    Type: AWS::KMS::Key
    Properties:
      Description: KMS key for CloudWatch Logs encryption
      KeyPolicy:
        Statement:
          - Effect: Allow
            Principal:
              Service: logs.amazonaws.com
            Action:
              - kms:Decrypt
              - kms:GenerateDataKey
            Resource: "*"
          - Effect: Allow
            Principal:
              AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
            Action:
              - kms:*
            Resource: "*"

  LogKeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: !Sub "${AWS::StackName}/logs-encryption"
      TargetKeyId: !Ref LogEncryptionKey

  # Encrypted log group
  EncryptedLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/encrypted/${ApplicationName}"
      RetentionInDays: 30
      KmsKeyId: !Ref LogEncryptionKey

Log Lifecycle Management

Automatic Log Expiration

Resources:
  # Short-term logs (7 days)
  ShortTermLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/temp/${ApplicationName}"
      RetentionInDays: 7

  # Medium-term logs (30 days)
  MediumTermLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/applications/${ApplicationName}"
      RetentionInDays: 30

  # Long-term logs (1 year)
  LongTermLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/audit/${ApplicationName}"
      RetentionInDays: 365

Cross-Account Logging

Centralized Logging Architecture

Resources:
  # Central logging account - destination
  CentralLogDestination:
    Type: AWS::Logs::Destination
    Properties:
      DestinationName: central-log-destination
      RoleArn: !Ref CentralDestinationRole
      TargetArn: !GetAtt CentralFirehose.Arn

  CentralDestinationRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: logs.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: PutRecordPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - firehose:PutRecord
                  - firehose:PutRecordBatch
                Resource: !GetAtt CentralFirehose.Arn

  # Source account - subscription
  SourceLogSubscription:
    Type: AWS::Logs::SubscriptionFilter
    Properties:
      DestinationArn: !Sub "arn:aws:logs:${CentralRegion}:${CentralAccountId}:destination:${CentralLogDestinationName}"
      LogGroupName: !Ref ApplicationLogGroup
      FilterPattern: '[timestamp, request_id, level, message]'
      RoleArn: !Ref SourceSubscriptionRole

Log Anomaly Detection

Anomaly Detection Filter

Resources:
  # Metric filter for anomaly detection
  AnomalyMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref ApplicationLogGroup
      FilterPattern: '[..., status]'
      MetricTransformations:
        - MetricName: AnomalousStatus
          MetricNamespace: !Sub "${AWS::StackName}/anomaly"
          MetricValue: "1"
          Unit: Count

CloudWatch Logs Insights Patterns

Search Patterns

Resources:
  ErrorPatternQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: error-search
      QueryString: |
        fields @timestamp, @message, level
        | filter level = "ERROR"
        | sort @timestamp desc
        | limit 100

  IPAddressQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: ip-address-extract
      QueryString: |
        fields @timestamp, @message
        | parse @message "user_ip=*" as user_ip
        | stats count(*) by user_ip
        | sort count desc

  DurationAnalysisQuery:
    Type: AWS::Logs::QueryDefinition
    Properties:
      Name: duration-analysis
      QueryString: |
        fields @timestamp, @duration
        | filter @duration > 0
        | stats avg(@duration), max(@duration), min(@duration), percentile(@duration, 50)

Live Tail Sessions

Live Tail Configuration

# Note: Live Tail is configured via AWS Console or CLI
# This is for reference - CloudFormation does not directly support Live Tail configuration

Resources:
  LogGroupForLiveTail:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/livetail/${ApplicationName}"
      RetentionInDays: 7

plugins

developer-kit-aws

skills

aws-cloudformation

README.md

CHANGELOG.md

context7.json

CONTRIBUTING.md

README_CN.md

README_ES.md

README_IT.md

README.md

tessl.json

tile.json