@factorypure/logger
v1.1.2
Published
Structured logging client for FactoryPure Node.js services. Writes log events to local files which are shipped to AWS CloudWatch Logs by the CloudWatch Agent running on the EC2 instance.
Keywords
Readme
@factorypure/logger
Structured logging client for FactoryPure Node.js services. Writes log events to local files which are shipped to AWS CloudWatch Logs by the CloudWatch Agent running on the EC2 instance.
How it works
Your app → /var/log/{service}/{StreamName}.log → CloudWatch Agent → AWS CloudWatch LogsEach named log stream writes to its own file. The CloudWatch Agent tails those files and batches them to CloudWatch every 5 seconds — no SDK calls from the application at runtime.
Setup
Logger options
| Option | Type | Required | Description |
| ------------------- | ------------------- | -------- | ---------------------------------------------------------------- |
| logGroupName | string | Yes | CloudWatch log group name (e.g. "FPJobs") |
| logDirectory | string | Yes* | Directory where log files are written (e.g. "/var/log/fpjobs") |
| asyncLocalStorage | AsyncLocalStorage | No | Attaches a request ID to every log line |
| notifyClient | Notify | No | Used to send Slack alerts on .fatal() |
| cloudWatchClient | CloudWatchLogs | No | Legacy SDK client — only needed if not using logDirectory |
*One of
logDirectoryorcloudWatchClientmust be provided.
Basic usage
import Logger from '@factorypure/logger'
import asyncLocalStorage from './localStorage.js'
import notifyClient from './notify.js'
const loggerClient = new Logger({
logGroupName: 'FPJobs',
logDirectory: '/var/log/fpjobs',
asyncLocalStorage,
notifyClient,
})
export const appLogger = loggerClient.createLogStream('App')
export default loggerClientLog methods
const logger = loggerClient.createLogStream('MyStream')
logger.info('Job started', { orderId: 123 })
logger.warn('Retrying request', attempt)
logger.error(new Error('Something failed'))
logger.fatal(new Error('Unrecoverable failure'), 'Optional description')
// .fatal() also sends a Slack alert to the fatal-error-log channelAdding a new log stream
Adding a new named stream requires three steps.
1. Call createLogStream in your job file
import loggerClient from '../helpers/logger.js'
const logger = loggerClient.createLogStream('MyNewStream')The logger will automatically create /var/log/fpjobs/MyNewStream.log on first use.
2. Add the stream to cloudwatch-agent-config.json
Open fpjobs/cloudwatch-agent-config.json and add an entry to the collect_list array:
{
"file_path": "/var/log/fpjobs/MyNewStream.log",
"log_group_name": "FPJobs",
"log_stream_name": "MyNewStream"
}3. Deploy
Commit and push both files. The CodeDeploy after_install.sh script will automatically reload the CloudWatch Agent with the updated config on the next deployment — no manual steps required.
Infrastructure overview
| Component | fpjobs | fpdash-server | Purpose |
| ----------------------- | ------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------- |
| Log files | /var/log/fpjobs/*.log | /var/log/fpdash-server/*.log | Written by the app, one file per stream |
| CloudWatch Agent config | fpjobs/cloudwatch-agent-config.json | fpdash-server/cloudwatch-agent-config.json | Maps each file to a CloudWatch stream |
| Log rotation config | fpjobs/logrotate.d/fpjobs | fpdash-server/logrotate.d/fpdash-server | Rotates logs daily, keeps 2 days |
| Deploy script | fpjobs/scripts/after_install.sh | fpdash-server/after_install.sh | Installs agent, applies config, sets up rotation on every deploy |
Log rotation
Logs are rotated daily by logrotate. Old files are compressed and kept for 2 days before deletion. copytruncate is used so the app's open file descriptor is not broken by rotation.
CloudWatch Agent
The agent runs as a systemd service (amazon-cloudwatch-agent) and starts automatically on instance reboot. It is installed automatically by after_install.sh if not already present, so new instances require no manual setup.
Verifying on the EC2 instance
# Confirm log files are being written
ls -la /var/log/fpjobs/
tail -f /var/log/fpjobs/App.log
# Confirm the agent is running
sudo systemctl status amazon-cloudwatch-agent
# Check agent logs for errors
sudo tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.logThen verify streams are appearing in the FPJobs log group in the AWS CloudWatch console.
