We will send logs from EC2 (Moodle) to Amazon CloudWatch Logs.
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/syslog",
"log_group_name": "MoodleSyslog",
"log_stream_name": "{instance_id}-syslog"
},
{
"file_path": "/var/log/apache2/access.log",
"log_group_name": "MoodleAccessLog",
"log_stream_name": "{instance_id}-access"
},
{
"file_path": "/var/log/apache2/error.log",
"log_group_name": "MoodleErrorLog",
"log_stream_name": "{instance_id}-error"
}
]
}
}
}
}
Go to AWS Lambda > Create function.
Select Author from scratch.
Function name: check-inactive-users
Runtime: Python 3.12
Execution role: Select the role you just created.
Click Create Function.
After creation, go to Source Code and enter the following code:
import logging
from datetime import datetime, timedelta
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
# This is a simulated user list from the Moodle system
users = [
{"username": "alice", "last_login": "2025-07-30"},
{"username": "bob", "last_login": "2025-07-25"},
]
today = datetime.utcnow().date()
threshold = today - timedelta(days=3)
for user in users:
last_login = datetime.strptime(user["last_login"], "%Y-%m-%d").date()
if last_login < threshold:
logger.info(f"User {user['username']} inactive since {last_login}")
return {"status": "done"}
Then select Deploy
Create an Event Bridge Rule to run Lambda daily
Go to Event Bridge on AWS Console -> Rule -> Create rule
Name: run-check-inactive-daily
Schedule: select Schedule → Continue in EventBridge Scheduler
Set as shown in the image below then click next
In the Setting section, set as shown in the image below, use the role created for lambda above.
Click next -> Create schedule
Go to Amazon SNS from AWS Console.
Select Topics → Click Create topic.
Name: notify-inactive-students
Type: Standard -> Create topic
Click Create subscription
In protocol -> select Email
Enter the email you want to receive alerts -> Create subscription and you will receive a confirmation email.
Click Confirm subscription.
Update Lambda to publish to SNS
Open the Lambda function you created earlier.
Update the Lambda code as follows
import json
import logging
import boto3
from datetime import datetime, timedelta
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# SNS topic ARN (replace this ARN with your actual ARN)
SNS_TOPIC_ARN = "arn:aws:sns:ap-southeast-1:456202168166:InactiveUsersTopic"
sns_client = boto3.client('sns')
def lambda_handler(event, context):
# Simulated user list (later can be fetched from Moodle API or DB)
users = [
{"username": "alice", "last_login": "2025-07-30"},
{"username": "bob", "last_login": "2025-07-25"},
{"username": "charlie", "last_login": "2025-07-20"},
]
today = datetime.utcnow().date()
threshold = today - timedelta(days=3)
inactive_users = []
for user in users:
last_login = datetime.strptime(user["last_login"], "%Y-%m-%d").date()
if last_login < threshold:
logger.info(f"User {user['username']} inactive since {last_login}")
inactive_users.append(user)
if inactive_users:
usernames = ", ".join([user['username'] for user in inactive_users])
message = f"Students inactive for more than 3 days: {usernames}"
# Send SNS
try:
response = sns_client.publish(
TopicArn=SNS_TOPIC_ARN, # Replace with your topic ARN, e.g. arn:aws:sns:ap-southeast-1:456202168166:notify-inactive-students
Message=message,
Subject="⚠️ Alert: Inactive Students"
)
logger.info(f"Sent alert via SNS: {response}")
except Exception as e:
logger.error(f"Error sending SNS message: {e}")
return {
"statusCode": 200,
"body": json.dumps(f"Checked {len(users)} users. Inactive: {len(inactive_users)}")
}
Redeploy the lambda function
Grant the Lambda IAM role the following permission by creating a new policy named AllowPublishToSNS.
Go to: IAM → Policies
Click “Create policy”
Select the Json tab and paste the following content.
Go back to the Lambda Role, select LambdaCheckInactiveUsersRole and attach the newly created policy
Go to Lambda Console
Select the function you want to test (e.g.: check-inactive-users)
Click the “Test” button (top right corner)
Select “Create new event”
Event name: test-inactive-users
Event JSON (leave empty if no input):{}
Click the “Test” button again
If you see the notification above, you have successfully tested the Lambda command, check your email for the Inactive user alert!
-> You have completed installing CloudWatch Agent to monitor system logs, created Lambda to check inactive students, and sent alerts via Amazon SNS if students do not log in for a long period.