Verified Commit f5b0e70d authored by Aral Balkan's avatar Aral Balkan
Browse files

Closes #157: add --access-log-errors-only and --access-log-disable

These options give you greater control over how much log output is presented for access attempts when a server (regular process or daemon) is running.
parent 00c0104f
......@@ -27,6 +27,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added
- `--access-log-errors-only` option when starting a server (regular process or daemon). (#157)
Displays only errors in the access log (HTTP status codes _4xx_ and _5xx_). Successful access requests (_1xx_, _2xx_, and _3xx_) are not logged. This is useful during development if you feel overwhelmed by the output and miss other, non-access-related errors.
- `--access-log-disable` option when starting a server (regular process or daemon). (#157)
Completely disable the access log. No access requests, _not even errors_ will be logged. Be careful when using this in production as you might miss important errors.
- Support for [custom Hugo 404 pages](https://gohugo.io/templates/404/) (#237).
Create a 404.html page in your `layouts/` folder so that it gets created in your `.generated` folder and it will be used instead of the default 404 page. If you have both a custom static 404 page (defined at /404/index.html) and a custom Hugo 404 page, the Hugo 404 page will take precedence.
......
......@@ -601,6 +601,10 @@ If `command` is omitted, behaviour defaults to `serve`.
- `--skip-domain-reachability-check`: Do not run pre-flight check for domain reachability.
- `--access-log-errors-only`: Display only errors in the access log (HTTP status codes _4xx_ and _5xx_). Successful access requests (_1xx_, _2xx_, and _3xx_) are not logged. This is useful during development if you feel overwhelmed by the output and miss other, non-access-related errors.
- `--access-log-disable`: Completely disable the access log. No access requests, _not even errors_ will be logged. Be careful when using this in production as you might miss important errors.
#### For the `serve` command:
- `--sync-to`: The host to sync to.
......
......@@ -89,6 +89,12 @@ function enable (args) {
// This will skip the domain reachability check when starting a global server.
const skipDomainReachabilityCheck = args.named['skip-domain-reachability-check'] === true ? ' --skip-domain-reachability-check ' : ''
// This will only show errors in the access log.
const accessLogErrorsOnly = args.named['access-log-errors-only'] === true ? ' --access-log-errors-only ' : ''
// This will disable the access log completely. Do not do this unless you have a good
// reason to as you may miss important errors.
const accessLogDisable = args.named['access-log-disable'] === true ? ' --access-log-disable ' : ''
// Expectation: At this point, regardless of whether we are running as a regular
// Node script or as a standalone executable created with Nexe, all paths should
......@@ -102,7 +108,7 @@ function enable (args) {
process.exit(1)
}
const launchCommand = `${executable} ${absolutePathToServe} @hostname ${domain} ${aliases} ${skipDomainReachabilityCheck}`
const launchCommand = `${executable} ${absolutePathToServe} @hostname ${domain} ${aliases} ${skipDomainReachabilityCheck} ${accessLogErrorsOnly} ${accessLogDisable}`
let accountName
try {
......
......@@ -21,6 +21,12 @@ const SYNC_FROM = 'sync-from'
const LIVE_SYNC = 'live-sync'
const SYNC_FOLDER_AND_CONTENTS = 'sync-folder-and-contents'
// This will only show errors in the access log (HTTP response codes 4xx and 5xx).
const ACCESS_LOG_ERRORS_ONLY = 'access-log-errors-only'
// This will disable the access log completely. Not even errors will be shown.
const ACCESS_LOG_DISABLE = 'access-log-disable'
// This will skip the domain reachability check when starting a global server. Useful if you are setting up a server
// where you know that the DNS has not propagated yet. Note that if you specify this flag, you double check that you’ve
// specified the domain and any aliases correctly as you will not be warned if you make a mistake.
......@@ -125,6 +131,13 @@ function serve (args) {
// Internal: exit on launch. (Used in pre-flight checks to ensure server can launch before installing a daemon.)
const exitAfterLaunch = args.named[EXIT_AFTER_LAUNCH]
const accessLogErrorsOnly = args.named[ACCESS_LOG_ERRORS_ONLY]
// Disable the access log (not even access errors will be shown).
// Note: if you want to quiet all messages, you must set the QUIET environment variable when running Site.js.
const accessLogDisable = args.named[ACCESS_LOG_DISABLE]
//
// Sync options.
//
......@@ -203,7 +216,9 @@ function serve (args) {
global,
proxyPort,
aliases,
skipDomainReachabilityCheck
skipDomainReachabilityCheck,
accessLogErrorsOnly,
accessLogDisable
}
if (syncRequested) {
......
......@@ -39,9 +39,8 @@ function status () {
console.log(`\n Path : ${clr(daemonDetails.pathBeingServed, textColour)}`)
console.log(` Domain : ${clr(daemonDetails.optionalOptions.domain, 'yellow') || clr(crossPlatformHostname, daemonDetails.optionalOptions.skipDomainReachabilityCheck && isActive ? 'yellow' : textColour)}`)
console.log(` Account: ${clr(daemonDetails.account, textColour)}`)
console.log(` Binary : ${clr(daemonDetails.siteJSBinary, textColour)}`)
if (daemonDetails.optionalOptions.aliases !== null) {
const aliasesString = daemonDetails.optionalOptions.aliases.reduce(
......@@ -51,6 +50,14 @@ function status () {
console.log(` Aliases: ${aliasesString.replace(/, $/, '')}`)
}
if (daemonDetails.optionalOptions.accessLogErrorsOnly && !daemonDetails.optionalOptions.accessLogDisable) {
console.log(`\n ${clr('Access log is only showing errors.', 'yellow')}`)
}
if (daemonDetails.optionalOptions.accessLogDisable) {
console.log(`\n ${clr('Access log is disabled (not even errors will be shown).', 'yellow')}`)
}
if (daemonDetails.optionalOptions.skipDomainReachabilityCheck) {
console.log(`\n ${clr('Domain reachability pre-flight check is disabled.', 'yellow')}`)
}
......
......@@ -79,6 +79,8 @@ class Help {
const optionEnsureCanSync = option('ensure-can-sync')
const optionLiveSync = option('live-sync')
const optionSyncFolderAndContents = option('sync-folder-and-contents')
const optionAccessLogErrorsOnly = option('access-log-errors-only')
const optionAccessLogDisable = option('access-log-disable')
// Black right-pointing triangle (U+25B6)
// (There are several similar unicode gylphs but this is the one that works well across
......@@ -139,6 +141,8 @@ class Help {
${optionDomain}\t\t\t\tThe main domain to serve (defaults to system hostname if not specified).
${optionAliases}\t\t\t\tAdditional domain aliases to obtain TLS certs for. Will 302 redirect to main domain.
${optionSkipDomainReachabilityCheck}\tDo not run pre-flight check for domain reachability.
${optionAccessLogErrorsOnly}\t\tDisplay only errors in the access log (HTTP status codes _4xx_ and _5xx_).
${optionAccessLogDisable}\t\tCompletely disable the access log. Not even errors are logged.
${ this.systemdExists ? `For ${commandServe} command:
` : '' }
......
......@@ -50,7 +50,7 @@ function status () {
const configuration = fs.readFileSync(path.join(path.sep, 'etc', 'systemd', 'system', 'site.js.service'), 'utf-8').trim().split('\n')
const account = configuration[8].trim().replace('User=', '')
const execStart = configuration[14].trim()
const execStart = configuration[14].trim().replace('=node ', '=')
// Launch configuration.
const binaryAndPathBeingServed = /ExecStart=(.*?) (.*?) @hostname/.exec(execStart)
......@@ -62,6 +62,8 @@ function status () {
const domain = (_domain = /--domain=(.*?)(\s|--|$)/.exec(execStart)) === null ? null : _domain[1]
const aliases = (_aliases = /--aliases=(.*?)(\s|--|$)/.exec(execStart)) === null ? null : _aliases[1].split(',')
const skipDomainReachabilityCheck = execStart.includes('--skip-domain-reachability-check')
const accessLogErrorsOnly = execStart.includes('--access-log-errors-only')
const accessLogDisable = execStart.includes('--access-log-disable')
let statisticsUrl = null
if (isActive) {
......@@ -72,7 +74,9 @@ function status () {
const optionalOptions = {
domain,
aliases,
skipDomainReachabilityCheck
skipDomainReachabilityCheck,
accessLogErrorsOnly,
accessLogDisable
}
daemonDetails = {
......
......@@ -275,6 +275,20 @@ class Site {
this.aliases = Array.isArray(options.aliases) ? options.aliases : []
this.syncHost = options.syncHost
this.skipDomainReachabilityCheck = options.skipDomainReachabilityCheck
this.accessLogErrorsOnly = options.accessLogErrorsOnly
this.accessLogDisable = options.accessLogDisable
if (this.skipDomainReachabilityCheck) {
this.log(` ⚠ ${clr('❨site.js❩ Domain reachability pre-flight check is disabled.', 'yellow')}`)
}
if (this.accessLogErrorsOnly && !this.accessLogDisable) {
this.log(` ⚠ ${clr('❨site.js❩ Access log is only showing errors.', 'yellow')}`)
}
if (this.accessLogDisable) {
this.log(` ⚠ ${clr('❨site.js❩ Access log is disabled (not even errors will be shown).', 'yellow')}`)
}
// Substitute shorthand www alias for full domain.
this.aliases = this.aliases.map(alias => alias === 'www' ? `www.${Site.hostname}` : alias)
......@@ -337,9 +351,12 @@ class Site {
this.app.use(this.stats.middleware)
// Logging.
this.app.use(morgan(function (tokens, req, res) {
this.app.use(morgan((tokens, req, res) => {
if (process.env.QUIET) {
const status = tokens.status(req, res)
const isError = status.startsWith('4') || status.startsWith('5')
if (process.env.QUIET || this.accessLogDisable || (this.accessLogErrorsOnly && !isError)) {
return
}
......@@ -404,17 +421,14 @@ class Site {
url = `📄 ${url}`
}
let status = tokens.status(req, res)
const statusToTextColour = {
'404': 'red',
'304': 'cyan',
'200': 'green',
}
let textColour = statusToTextColour[status]
if (hasWarning) { textColour = 'yellow' }
if (hasError) { textColour = 'red' }
if (hasError || isError) { textColour = 'red' }
const log = [
clr(method, textColour),
......
......@@ -404,6 +404,8 @@ test('[commands] help', t => {
--domain The main domain to serve (defaults to system hostname if not specified).
--aliases Additional domain aliases to obtain TLS certs for. Will 302 redirect to main domain.
--skip-domain-reachability-check Do not run pre-flight check for domain reachability.
--access-log-errors-only Display only errors in the access log (HTTP status codes _4xx_ and _5xx_).
--access-log-disable Completely disable the access log. Not even errors are logged.
For serve command:
......@@ -511,6 +513,8 @@ test('[commands] help', t => {
--domain The main domain to serve (defaults to system hostname if not specified).
--aliases Additional domain aliases to obtain TLS certs for. Will 302 redirect to main domain.
--skip-domain-reachability-check Do not run pre-flight check for domain reachability.
--access-log-errors-only Display only errors in the access log (HTTP status codes _4xx_ and _5xx_).
--access-log-disable Completely disable the access log. Not even errors are logged.
--sync-to The host to sync to (other sync options only relevant if this is supplied).
--sync-from The folder to sync from.
......@@ -600,6 +604,8 @@ test('[commands] help', t => {
--domain The main domain to serve (defaults to system hostname if not specified).
--aliases Additional domain aliases to obtain TLS certs for. Will 302 redirect to main domain.
--skip-domain-reachability-check Do not run pre-flight check for domain reachability.
--access-log-errors-only Display only errors in the access log (HTTP status codes _4xx_ and _5xx_).
--access-log-disable Completely disable the access log. Not even errors are logged.
--sync-to The host to sync to (other sync options only relevant if this is supplied).
--sync-from The folder to sync from.
......@@ -686,6 +692,8 @@ test('[commands] help', t => {
--domain The main domain to serve (defaults to system hostname if not specified).
--aliases Additional domain aliases to obtain TLS certs for. Will 302 redirect to main domain.
--skip-domain-reachability-check Do not run pre-flight check for domain reachability.
--access-log-errors-only Display only errors in the access log (HTTP status codes _4xx_ and _5xx_).
--access-log-disable Completely disable the access log. Not even errors are logged.
--sync-to The host to sync to (other sync options only relevant if this is supplied).
--sync-from The folder to sync from.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment