Skip to content

Commit 4521a6d

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/webpack-8e325d9a6b
2 parents 7d92bce + 0e8129a commit 4521a6d

2 files changed

Lines changed: 122 additions & 46 deletions

File tree

docker-compose.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# A Docker Compose file for running the production build locally.
2+
# Usage:
3+
# docker compose up -d --build --force-recreate
4+
services:
5+
tag-page-rendering:
6+
build:
7+
dockerfile: ./Production.dockerfile
8+
environment:
9+
NODE_ENV: production
10+
GU_STAGE: PROD
11+
GU_APP: tag-page-rendering
12+
GU_STACK: frontend
13+
14+
# We configure Log4JS based on this environment variable. See `server/lib/logging.ts`.
15+
AWS_EXECUTION_ENV: AWS_ECS_LOCAL
16+
17+
# Explicitly tell AWS SDK where to find credentials
18+
AWS_SHARED_CREDENTIALS_FILE: /.aws/credentials
19+
ports:
20+
- '9000:9000'
21+
22+
# Share the host's AWS credentials with the container
23+
volumes:
24+
- ${HOME}/.aws/credentials:/.aws/credentials:ro
25+
26+
# In Production.dockerfile, we're deliberately using a minimal image that does not have `curl` installed.
27+
# Therefore, we're using Node to make a request to the healthcheck endpoint instead of using `curl`.
28+
healthcheck:
29+
test:
30+
[
31+
'CMD',
32+
'node',
33+
'-e',
34+
"fetch('http://localhost:9000/_healthcheck').then(_ => process.exit(0)).catch(_ => process.exit(1))",
35+
]
36+
interval: 10s
37+
timeout: 5s
38+
retries: 5
39+
40+
# This service is used to make a sample request to tag-page-rendering only after it has started and is healthy.
41+
# It exits immediately after making the request, so it is not a long-running service.
42+
# View the logs via:
43+
# docker logs "$(docker ps -aq --filter "name=sample-request" --latest)"
44+
# The log output is the DCR response, so we can also pipe it through `jq` to pretty-print it, e.g.:
45+
# docker logs "$(docker ps -aq --filter "name=sample-request" --latest)" | jq .
46+
sample-request:
47+
image: curlimages/curl:8.21.0
48+
depends_on:
49+
tag-page-rendering:
50+
condition: service_healthy
51+
command: |
52+
curl "https://www.theguardian.com/tone/minutebyminute.json?dcr=true" --silent > data.json && \
53+
curl -X POST http://localhost:9000/TagPage -d @data.json -H "Content-Type: application/json"

dotcom-rendering/src/server/lib/logging.ts

Lines changed: 69 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ import type { Configuration, Layout, LoggingEvent } from 'log4js';
44
import { addLayout, configure, getLogger, shutdown } from 'log4js';
55
import { type DCRLoggingStore, loggingStore } from './logging-store';
66

7-
const logName = `dotcom-rendering.log`;
8-
9-
const logLocation =
10-
process.env.NODE_ENV === 'production' &&
11-
!process.env.DISABLE_LOGGING_AND_METRICS
12-
? `/var/log/dotcom-rendering/${logName}`
13-
: `${path.resolve('logs')}/${logName}`;
14-
157
type LogFields = Partial<DCRLoggingStore> &
168
Record<string | number | symbol, unknown>;
179

@@ -84,39 +76,69 @@ const disableLog4js: Configuration = {
8476
},
8577
};
8678

87-
const enableLog4js: Configuration = {
88-
appenders: {
89-
console: {
90-
type: 'console',
91-
layout: consoleLayout,
79+
function configureLog4jsEC2() {
80+
const logName = `dotcom-rendering.log`;
81+
82+
const logLocation =
83+
process.env.NODE_ENV === 'production' &&
84+
!process.env.DISABLE_LOGGING_AND_METRICS
85+
? `/var/log/dotcom-rendering/${logName}`
86+
: `${path.resolve('logs')}/${logName}`;
87+
88+
configure({
89+
appenders: {
90+
console: {
91+
type: 'console',
92+
layout: consoleLayout,
93+
},
94+
fileAppender: {
95+
type: 'file',
96+
filename: logLocation,
97+
maxLogSize: '5M',
98+
backups: 5,
99+
compress: true,
100+
layout: { type: 'json', separator: ',' },
101+
// Owner Read & Write, Group Read
102+
mode: 0o640,
103+
},
104+
out: {
105+
type: 'stdout',
106+
layout: { type: 'json', separator: ',' },
107+
},
92108
},
93-
fileAppender: {
94-
type: 'file',
95-
filename: logLocation,
96-
maxLogSize: '5M',
97-
backups: 5,
98-
compress: true,
99-
layout: { type: 'json', separator: ',' },
100-
// Owner Read & Write, Group Read
101-
mode: 0o640,
109+
categories: {
110+
default: { appenders: ['out'], level: 'off' },
111+
production: { appenders: ['out', 'fileAppender'], level: 'info' },
112+
code: { appenders: ['out', 'fileAppender'], level: 'debug' },
113+
development: { appenders: ['console'], level: 'debug' },
102114
},
103-
out: {
104-
type: 'stdout',
105-
layout: { type: 'json', separator: ',' },
115+
// log4js cluster mode handling does not work as it prevents
116+
// logs from processes other than the main process from
117+
// writing to the log.
118+
disableClustering: true,
119+
});
120+
}
121+
122+
function configureLog4jsECS() {
123+
configure({
124+
appenders: {
125+
out: {
126+
type: 'stdout',
127+
layout: { type: 'json', separator: ',' },
128+
},
106129
},
107-
},
108-
categories: {
109-
default: { appenders: ['out'], level: 'off' },
110-
production: { appenders: ['out', 'fileAppender'], level: 'info' },
111-
code: { appenders: ['out', 'fileAppender'], level: 'debug' },
112-
development: { appenders: ['console'], level: 'debug' },
113-
container: { appenders: ['out'], level: 'info' },
114-
},
115-
// log4js cluster mode handling does not work as it prevents
116-
// logs from processes other than the main process from
117-
// writing to the log.
118-
disableClustering: true,
119-
};
130+
categories: {
131+
default: { appenders: ['out'], level: 'info' },
132+
production: { appenders: ['out'], level: 'info' },
133+
code: { appenders: ['out'], level: 'debug' },
134+
development: { appenders: ['out'], level: 'debug' },
135+
},
136+
// log4js cluster mode handling does not work as it prevents
137+
// logs from processes other than the main process from
138+
// writing to the log.
139+
disableClustering: true,
140+
});
141+
}
120142

121143
// We do this to ensure no memory leaks during development as hot reloading
122144
// doesn't clear up old listeners.
@@ -132,20 +154,21 @@ if (process.env.NODE_ENV === 'development') {
132154
if (process.env.DISABLE_LOGGING_AND_METRICS === 'true') {
133155
configure(disableLog4js);
134156
} else {
135-
configure(enableLog4js);
157+
// See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html
158+
const runningInECS =
159+
process.env.AWS_EXECUTION_ENV?.startsWith('AWS_ECS_') === true;
160+
161+
if (runningInECS) {
162+
configureLog4jsECS();
163+
} else {
164+
configureLog4jsEC2();
165+
}
136166
}
137167

138168
const getLoggerCategory = (): string => {
139169
if (process.env.DISABLE_LOGGING_AND_METRICS === 'true') {
140170
return 'off';
141171
}
142-
143-
// Are we running in a container?
144-
// See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html
145-
if (process.env.AWS_EXECUTION_ENV?.startsWith('AWS_ECS_') === true) {
146-
return 'container';
147-
}
148-
149172
if (process.env.NODE_ENV === 'development') {
150173
return 'development';
151174
}

0 commit comments

Comments
 (0)