mirror of
https://github.com/digitalocean/nginxconfig.io
synced 2024-11-10 04:24:12 +00:00
Move logging configuration to be per-domain (#399)
* chore: per-domain logging * fix: lint * fix: revert cdn configuration disabling the access log * feat: more granular controls for logging * chore(cr): bump copyright year to 2022 * fix(cr): missing error_log level in the global config * fix(cr): `is-changed` indicators * chore(cr): newline at end of file + eslint enforcement * fix(cr): rows alignment when checkbox applies * fix(cr): don't use default computed values * fix: lint * chore: use new flag names to allow backward compatability * chore: global `access_log` should always be `off` * feat: migrate old logging to new * feat: option to turn on access_log and error_log on redirects * fix: update copyright year * fix: missing translation * fix(cr): migration from global `error_log` being empty * fix(cr): missing `return` * fix(cr): account for a `server` dictionary without `domain` * fix(cr): migrate previous `access_log` and `error_log` paths using the previous behavior * chore(cr): additional logging comment * feat(cr): disable error_log per domain * fix(logging): use default paths * fix(logging): retain the user values for error_log when toggling the log on/off * fix(bc): new params shouldn't be overridden
This commit is contained in:
parent
f44832ed7a
commit
e2a95a5ed4
31 changed files with 406 additions and 77 deletions
|
@ -30,6 +30,7 @@ module.exports = {
|
||||||
'vue/html-self-closing': 0,
|
'vue/html-self-closing': 0,
|
||||||
'vue/multi-word-component-names': 0,
|
'vue/multi-word-component-names': 0,
|
||||||
'vue/no-reserved-component-names': 0,
|
'vue/no-reserved-component-names': 0,
|
||||||
|
'eol-last': ['error', 'always'],
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
'describe': true,
|
'describe': true,
|
||||||
|
|
|
@ -33,13 +33,11 @@ export default (domains, global) => {
|
||||||
config['location = /favicon.ico'] = {
|
config['location = /favicon.ico'] = {
|
||||||
log_not_found: 'off',
|
log_not_found: 'off',
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config['location = /favicon.ico'].access_log = 'off';
|
|
||||||
|
|
||||||
config['# robots.txt'] = '';
|
config['# robots.txt'] = '';
|
||||||
config['location = /robots.txt'] = {
|
config['location = /robots.txt'] = {
|
||||||
log_not_found: 'off',
|
log_not_found: 'off',
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config['location = /robots.txt'].access_log = 'off';
|
|
||||||
|
|
||||||
if (global.performance.disableHtmlCaching.computed) {
|
if (global.performance.disableHtmlCaching.computed) {
|
||||||
// Disable HTML caching for changes take effect in time
|
// Disable HTML caching for changes take effect in time
|
||||||
|
@ -48,7 +46,6 @@ export default (domains, global) => {
|
||||||
config[loc] = {
|
config[loc] = {
|
||||||
add_header: 'Cache-Control "no-cache"',
|
add_header: 'Cache-Control "no-cache"',
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +58,6 @@ export default (domains, global) => {
|
||||||
config[loc] = {
|
config[loc] = {
|
||||||
expires: global.performance.assetsExpiration.computed,
|
expires: global.performance.assetsExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Assets & media separately
|
// Assets & media separately
|
||||||
|
@ -71,7 +67,6 @@ export default (domains, global) => {
|
||||||
config[loc] = {
|
config[loc] = {
|
||||||
expires: global.performance.assetsExpiration.computed,
|
expires: global.performance.assetsExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.performance.mediaExpiration.computed) {
|
if (global.performance.mediaExpiration.computed) {
|
||||||
|
@ -80,7 +75,6 @@ export default (domains, global) => {
|
||||||
config[loc] = {
|
config[loc] = {
|
||||||
expires: global.performance.mediaExpiration.computed,
|
expires: global.performance.mediaExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +87,6 @@ export default (domains, global) => {
|
||||||
add_header: 'Access-Control-Allow-Origin "*"',
|
add_header: 'Access-Control-Allow-Origin "*"',
|
||||||
expires: global.performance.svgExpiration.computed,
|
expires: global.performance.svgExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// SVG & fonts separately
|
// SVG & fonts separately
|
||||||
|
@ -104,7 +97,6 @@ export default (domains, global) => {
|
||||||
add_header: 'Access-Control-Allow-Origin "*"',
|
add_header: 'Access-Control-Allow-Origin "*"',
|
||||||
expires: global.performance.svgExpiration.computed,
|
expires: global.performance.svgExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.performance.fontsExpiration.computed) {
|
if (global.performance.fontsExpiration.computed) {
|
||||||
|
@ -114,7 +106,6 @@ export default (domains, global) => {
|
||||||
add_header: 'Access-Control-Allow-Origin "*"',
|
add_header: 'Access-Control-Allow-Origin "*"',
|
||||||
expires: global.performance.fontsExpiration.computed,
|
expires: global.performance.fontsExpiration.computed,
|
||||||
};
|
};
|
||||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,6 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { errorLogPathDisabled } from '../../util/logging';
|
||||||
import sslProfiles from '../../util/ssl_profiles';
|
import sslProfiles from '../../util/ssl_profiles';
|
||||||
import websiteConf from './website.conf';
|
import websiteConf from './website.conf';
|
||||||
|
|
||||||
|
@ -107,8 +108,13 @@ export default (domains, global) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
config.http.push(['# Logging', '']);
|
config.http.push(['# Logging', '']);
|
||||||
config.http.push(['access_log', (global.logging.accessLog.computed.trim() + (global.logging.cloudflare.computed ? ' cloudflare' : '')) || 'off']);
|
config.http.push(['access_log', 'off']);
|
||||||
config.http.push(['error_log', global.logging.errorLog.computed.trim() || '/dev/null']);
|
if (global.logging.errorLogEnabled.computed) {
|
||||||
|
config.http.push(['error_log', global.logging.errorLogPath.computed.trim() +
|
||||||
|
` ${global.logging.errorLogLevel.computed}`]);
|
||||||
|
} else {
|
||||||
|
config.http.push(['error_log', errorLogPathDisabled]);
|
||||||
|
}
|
||||||
|
|
||||||
if (global.security.limitReq.computed) {
|
if (global.security.limitReq.computed) {
|
||||||
config.http.push(['# Limits', '']);
|
config.http.push(['# Limits', '']);
|
||||||
|
|
|
@ -25,8 +25,8 @@ THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getSslCertificate, getSslCertificateKey } from '../../util/get_ssl_certificate';
|
import { getSslCertificate, getSslCertificateKey } from '../../util/get_ssl_certificate';
|
||||||
import { getAccessLogDomainPath, getErrorLogDomainPath } from '../../util/get_log_paths';
|
|
||||||
import { extensions, gzipTypes } from '../../util/types_extensions';
|
import { extensions, gzipTypes } from '../../util/types_extensions';
|
||||||
|
import { getDomainAccessLog, getDomainErrorLog } from '../../util/logging';
|
||||||
import commonHsts from '../../util/common_hsts';
|
import commonHsts from '../../util/common_hsts';
|
||||||
import securityConf from './security.conf';
|
import securityConf from './security.conf';
|
||||||
import pythonConf from './python_uwsgi.conf';
|
import pythonConf from './python_uwsgi.conf';
|
||||||
|
@ -127,6 +127,19 @@ const httpRedirectConfig = (domain, global, ipPortPairs, domainName, redirectDom
|
||||||
config.push(...httpListen(domain, global, ipPortPairs));
|
config.push(...httpListen(domain, global, ipPortPairs));
|
||||||
config.push(['server_name', domainName]);
|
config.push(['server_name', domainName]);
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
if (domain.logging.redirectAccessLog.computed || domain.logging.redirectErrorLog.computed) {
|
||||||
|
config.push(['# logging', '']);
|
||||||
|
|
||||||
|
if (domain.logging.redirectAccessLog.computed) {
|
||||||
|
config.push(['access_log', getDomainAccessLog(domain, global)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain.logging.redirectErrorLog.computed) {
|
||||||
|
config.push(['error_log', getDomainErrorLog(domain)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (domain.https.certType.computed === 'letsEncrypt') {
|
if (domain.https.certType.computed === 'letsEncrypt') {
|
||||||
// Let's encrypt
|
// Let's encrypt
|
||||||
|
|
||||||
|
@ -221,15 +234,14 @@ export default (domain, domains, global, ipPortPairs) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access log or error log for domain
|
// Access log or error log for domain
|
||||||
if (domain.logging.accessLog.computed || domain.logging.errorLog.computed) {
|
if (domain.logging.accessLogEnabled.computed || domain.logging.errorLogEnabled.computed) {
|
||||||
serverConfig.push(['# logging', '']);
|
serverConfig.push(['# logging', '']);
|
||||||
|
|
||||||
if (domain.logging.accessLog.computed)
|
if (domain.logging.accessLogEnabled.computed)
|
||||||
serverConfig.push(['access_log',
|
serverConfig.push(['access_log', getDomainAccessLog(domain, global)]);
|
||||||
getAccessLogDomainPath(domain, global) + (global.logging.cloudflare.computed ? ' cloudflare' : '')]);
|
|
||||||
|
|
||||||
if (domain.logging.errorLog.computed)
|
if (domain.logging.errorLogEnabled.computed)
|
||||||
serverConfig.push(['error_log', getErrorLogDomainPath(domain, global)]);
|
serverConfig.push(['error_log', getDomainErrorLog(domain)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// index.php
|
// index.php
|
||||||
|
@ -411,7 +423,19 @@ export default (domain, domains, global, ipPortPairs) => {
|
||||||
|
|
||||||
// HTTPS
|
// HTTPS
|
||||||
redirectConfig.push(...sslConfig(domain, global));
|
redirectConfig.push(...sslConfig(domain, global));
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
if (domain.logging.redirectAccessLog.computed || domain.logging.redirectErrorLog.computed) {
|
||||||
|
redirectConfig.push(['# logging', '']);
|
||||||
|
|
||||||
|
if (domain.logging.redirectAccessLog.computed) {
|
||||||
|
redirectConfig.push(['access_log', getDomainAccessLog(domain, global)]);
|
||||||
|
}
|
||||||
|
if (domain.logging.redirectErrorLog.computed) {
|
||||||
|
redirectConfig.push(['error_log', getDomainErrorLog(domain)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
redirectConfig.push(['return',
|
redirectConfig.push(['return',
|
||||||
`301 http${domain.https.https.computed ? 's' : ''}://${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}$request_uri`]);
|
`301 http${domain.https.https.computed ? 's' : ''}://${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}$request_uri`]);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -27,4 +27,7 @@ THE SOFTWARE.
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'der Domain',
|
byDomain: 'der Domain',
|
||||||
enableForThisDomain: 'Für diese Domain aktivieren',
|
enableForThisDomain: 'Für diese Domain aktivieren',
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} "Seite nicht gefunden" Error Logging in`,
|
enableFileNotFoundErrorLogging: `${common.enable} "Seite nicht gefunden" Error Logging in`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'Füge Cloudflare Anfrage-Header dem Standard Log-Format hinzu',
|
enableCloudflare: 'Füge Cloudflare Anfrage-Header dem Standard Log-Format hinzu',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'by domain',
|
byDomain: 'by domain',
|
||||||
enableForThisDomain: `${common.enable} for this domain`,
|
enableForThisDomain: `${common.enable} for this domain`,
|
||||||
|
arguments: 'arguments',
|
||||||
|
level: 'logging level',
|
||||||
|
forRedirects: 'for redirects',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} file not found error logging in`,
|
enableFileNotFoundErrorLogging: `${common.enable} file not found error logging in`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level',
|
||||||
enableCloudflare: 'add Cloudflare request headers to the default log format',
|
enableCloudflare: 'add Cloudflare request headers to the default log format',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'por dominio',
|
byDomain: 'por dominio',
|
||||||
enableForThisDomain: `${common.enable} para este dominio`,
|
enableForThisDomain: `${common.enable} para este dominio`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} el registro de error de archivo no encontrado`,
|
enableFileNotFoundErrorLogging: `${common.enable} el registro de error de archivo no encontrado`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'agregar cabecera de petición de Cloudflare en el formato por defecto del registro',
|
enableCloudflare: 'agregar cabecera de petición de Cloudflare en el formato por defecto del registro',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'par domaine',
|
byDomain: 'par domaine',
|
||||||
enableForThisDomain: `${common.enable} pour ce domaine`,
|
enableForThisDomain: `${common.enable} pour ce domaine`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} les erreurs de fichiers introuvables lors de la journalisation`,
|
enableFileNotFoundErrorLogging: `${common.enable} les erreurs de fichiers introuvables lors de la journalisation`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'ajouter les en-têtes de requête CloudFlare au format de journal par défaut',
|
enableCloudflare: 'ajouter les en-têtes de requête CloudFlare au format de journal par défaut',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: '(ドメインごと)',
|
byDomain: '(ドメインごと)',
|
||||||
enableForThisDomain: `このドメインで${common.enable}`,
|
enableForThisDomain: `このドメインで${common.enable}`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `FILE NOT FOUND エラーのロギングを${common.enable}`,
|
enableFileNotFoundErrorLogging: `FILE NOT FOUND エラーのロギングを${common.enable}`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'デフォルトのログフォーマットに Cloudflare のリクエストヘッダを追加する',
|
enableCloudflare: 'デフォルトのログフォーマットに Cloudflare のリクエストヘッダを追加する',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'wg. domen',
|
byDomain: 'wg. domen',
|
||||||
enableForThisDomain: `${common.enable} dla tej domeny`,
|
enableForThisDomain: `${common.enable} dla tej domeny`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} logowanie błędów o nieznalezionych plikach`,
|
enableFileNotFoundErrorLogging: `${common.enable} logowanie błędów o nieznalezionych plikach`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'dodaj nagłówki żądań Cloudflare do domyślnego formatu dziennika ',
|
enableCloudflare: 'dodaj nagłówki żądań Cloudflare do domyślnego formatu dziennika ',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'por domínio',
|
byDomain: 'por domínio',
|
||||||
enableForThisDomain: `${common.enable} para este domínio`,
|
enableForThisDomain: `${common.enable} para este domínio`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} erro de arquivo não encontrado ao fazer login`,
|
enableFileNotFoundErrorLogging: `${common.enable} erro de arquivo não encontrado ao fazer login`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'adicionar cabeçalhos de solicitação Cloudflare ao formato de log padrão',
|
enableCloudflare: 'adicionar cabeçalhos de solicitação Cloudflare ao formato de log padrão',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: 'по домену',
|
byDomain: 'по домену',
|
||||||
enableForThisDomain: `${common.enable} для этого домена`,
|
enableForThisDomain: `${common.enable} для этого домена`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable} логирование ошибок для файлов, которые не были найдены при запросе`,
|
enableFileNotFoundErrorLogging: `${common.enable} логирование ошибок для файлов, которые не были найдены при запросе`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: 'добавить Cloudflare хедеры запроса в дефолтный формат логов',
|
enableCloudflare: 'добавить Cloudflare хедеры запроса в дефолтный формат логов',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: '在此站点',
|
byDomain: '在此站点',
|
||||||
enableForThisDomain: `为此站点${common.enable}`,
|
enableForThisDomain: `为此站点${common.enable}`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable}“文件未找到”错误日志:`,
|
enableFileNotFoundErrorLogging: `${common.enable}“文件未找到”错误日志:`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: '将Cloudflare请求头部添加到默认日志格式',
|
enableCloudflare: '将Cloudflare请求头部添加到默认日志格式',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -29,4 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
byDomain: '在此網域',
|
byDomain: '在此網域',
|
||||||
enableForThisDomain: `為此網域${common.enable}`,
|
enableForThisDomain: `為此網域${common.enable}`,
|
||||||
|
arguments: 'arguments', // TODO: translate
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
|
forRedirects: 'for redirects', // TODO: translate
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@ import common from '../../common';
|
||||||
export default {
|
export default {
|
||||||
enableFileNotFoundErrorLogging: `${common.enable}「找不到檔案」錯誤日誌:`,
|
enableFileNotFoundErrorLogging: `${common.enable}「找不到檔案」錯誤日誌:`,
|
||||||
logformat: 'log_format',
|
logformat: 'log_format',
|
||||||
|
level: 'logging level', // TODO: translate
|
||||||
enableCloudflare: '將 Cloudflare 請求標頭加入預設日誌格式',
|
enableCloudflare: '將 Cloudflare 請求標頭加入預設日誌格式',
|
||||||
cfRay: 'CF-Ray',
|
cfRay: 'CF-Ray',
|
||||||
cfConnectingIp: 'CF-Connecting-IP',
|
cfConnectingIp: 'CF-Connecting-IP',
|
||||||
|
|
|
@ -227,6 +227,7 @@ THE SOFTWARE.
|
||||||
import ExternalLink from 'do-vue/src/templates/external_link';
|
import ExternalLink from 'do-vue/src/templates/external_link';
|
||||||
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
||||||
import computedFromDefaults from '../../util/computed_from_defaults';
|
import computedFromDefaults from '../../util/computed_from_defaults';
|
||||||
|
import { serverDomainDefault } from '../../util/defaults';
|
||||||
import PrettyCheck from '../inputs/checkbox';
|
import PrettyCheck from '../inputs/checkbox';
|
||||||
import PrettyRadio from '../inputs/radio';
|
import PrettyRadio from '../inputs/radio';
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ THE SOFTWARE.
|
||||||
},
|
},
|
||||||
letsEncryptEmail: {
|
letsEncryptEmail: {
|
||||||
default: '',
|
default: '',
|
||||||
computed: 'info@example.com', // No default value, but a default computed
|
computed: `info@${serverDomainDefault}`, // No default value, but a default computed
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
sslCertificate: {
|
sslCertificate: {
|
||||||
|
|
|
@ -26,35 +26,124 @@ THE SOFTWARE.
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="field is-horizontal">
|
<div class="field is-horizontal is-aligned-top">
|
||||||
<div class="field-label">
|
<div class="field-label has-small-margin-top">
|
||||||
<label class="label">access_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
|
<label class="label">access_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div :class="`control${accessLogChanged ? ' is-changed' : ''}`">
|
<div :class="`control${accessLogEnabledChanged ? ' is-changed' : ''}`">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<PrettyCheck v-model="accessLog" class="p-default p-curve p-fill p-icon">
|
<PrettyCheck v-model="accessLogEnabled" class="p-default p-curve p-fill p-icon">
|
||||||
{{ $t('templates.domainSections.logging.enableForThisDomain') }}
|
{{ $t('templates.domainSections.logging.enableForThisDomain') }}
|
||||||
</PrettyCheck>
|
</PrettyCheck>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="$props.data.accessLogEnabled.computed" :class="`control field is-horizontal is-expanded${accessLogPathChanged ? ' is-changed' : ''}`">
|
||||||
|
<input
|
||||||
|
v-model="accessLogPath"
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$props.data.accessLogPath.default"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="$props.data.accessLogEnabled.computed" class="field is-horizontal">
|
||||||
|
<div class="field-label">
|
||||||
|
<label class="label">access_log {{ $t('templates.domainSections.logging.arguments') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div :class="`control${accessLogParametersChanged ? ' is-changed' : ''}`">
|
||||||
|
<input
|
||||||
|
v-model="accessLogParameters"
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$props.data.accessLogParameters.default"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal is-aligned-top">
|
||||||
|
<div class="field-label has-small-margin-top">
|
||||||
|
<label class="label">access_log {{ $t('templates.domainSections.logging.forRedirects') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div :class="`control${redirectAccessLogChanged ? ' is-changed' : ''}`">
|
||||||
|
<div class="checkbox">
|
||||||
|
<PrettyCheck v-model="redirectAccessLog" class="p-default p-curve p-fill p-icon">
|
||||||
|
{{ $t('common.enable') }}
|
||||||
|
</PrettyCheck>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
<div class="field is-horizontal is-aligned-top">
|
||||||
<div class="field-label">
|
<div class="field-label has-small-margin-top">
|
||||||
<label class="label">error_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
|
<label class="label">error_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div :class="`control${errorLogChanged ? ' is-changed' : ''}`">
|
<div :class="`control${errorLogEnabledChanged ? ' is-changed' : ''}`">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<PrettyCheck v-model="errorLog" class="p-default p-curve p-fill p-icon">
|
<PrettyCheck v-model="errorLogEnabled" class="p-default p-curve p-fill p-icon">
|
||||||
{{ $t('templates.domainSections.logging.enableForThisDomain') }}
|
{{ $t('templates.domainSections.logging.enableForThisDomain') }}
|
||||||
</PrettyCheck>
|
</PrettyCheck>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="$props.data.errorLogEnabled.computed" :class="`control field is-horizontal is-expanded${errorLogPathChanged ? ' is-changed' : ''}`">
|
||||||
|
<input
|
||||||
|
v-model="errorLogPath"
|
||||||
|
class="input"
|
||||||
|
type="text"
|
||||||
|
:disabled="!errorLogPathEnabled"
|
||||||
|
:placeholder="$props.data.errorLogPath.default"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="$props.data.errorLogEnabled.computed" class="field is-horizontal">
|
||||||
|
<div class="field-label">
|
||||||
|
<label class="label">error_log {{ $t('templates.domainSections.logging.level') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div
|
||||||
|
v-for="value in $props.data.errorLogLevel.options"
|
||||||
|
:class="`control${errorLogLevelChanged && value === errorLogLevel ? ' is-changed' : ''}`"
|
||||||
|
>
|
||||||
|
<div class="radio">
|
||||||
|
<PrettyRadio v-model="errorLogLevel" :value="value" class="p-default p-round p-fill p-icon">
|
||||||
|
{{ value }}
|
||||||
|
</PrettyRadio>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal is-aligned-top">
|
||||||
|
<div class="field-label has-small-margin-top">
|
||||||
|
<label class="label">error_log {{ $t('templates.domainSections.logging.forRedirects') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div :class="`control${redirectErrorLogChanged ? ' is-changed' : ''}`">
|
||||||
|
<div class="checkbox">
|
||||||
|
<PrettyCheck v-model="redirectErrorLog" class="p-default p-curve p-fill p-icon">
|
||||||
|
{{ $t('common.enable') }}
|
||||||
|
</PrettyCheck>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,14 +154,41 @@ THE SOFTWARE.
|
||||||
<script>
|
<script>
|
||||||
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
||||||
import computedFromDefaults from '../../util/computed_from_defaults';
|
import computedFromDefaults from '../../util/computed_from_defaults';
|
||||||
|
import { accessLogPathDefault, accessLogParamsDefault, errorLogPathDefault, errorLogPathDisabled, errorLogLevelDefault, errorLogLevelOptions, errorLogLevelDisabled } from '../../util/logging';
|
||||||
import PrettyCheck from '../inputs/checkbox';
|
import PrettyCheck from '../inputs/checkbox';
|
||||||
|
import PrettyRadio from '../inputs/radio';
|
||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
accessLog: {
|
accessLogEnabled: {
|
||||||
|
default: true,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
accessLogPath: {
|
||||||
|
default: accessLogPathDefault,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
accessLogParameters: {
|
||||||
|
default: accessLogParamsDefault,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
redirectAccessLog: {
|
||||||
default: false,
|
default: false,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
errorLog: {
|
errorLogEnabled: {
|
||||||
|
default: true,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
errorLogPath: {
|
||||||
|
default: errorLogPathDefault,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
errorLogLevel: {
|
||||||
|
default: errorLogLevelDefault,
|
||||||
|
options: [errorLogLevelDisabled, ...errorLogLevelOptions],
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
redirectErrorLog: {
|
||||||
default: false,
|
default: false,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
|
@ -85,10 +201,26 @@ THE SOFTWARE.
|
||||||
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
|
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
|
||||||
components: {
|
components: {
|
||||||
PrettyCheck,
|
PrettyCheck,
|
||||||
|
PrettyRadio,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
data: Object, // Data delegated back to us from parent
|
data: Object, // Data delegated back to us from parent
|
||||||
},
|
},
|
||||||
computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data
|
computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data
|
||||||
|
watch: {
|
||||||
|
'$props.data.errorLogLevel': {
|
||||||
|
handler(data) {
|
||||||
|
// disable `error_log` path selection if log level is set to `none`
|
||||||
|
if (data.computed === errorLogLevelDisabled) {
|
||||||
|
this.$props.data.errorLogPath.enabled = false;
|
||||||
|
this.$props.data.errorLogPath.computed = errorLogPathDisabled;
|
||||||
|
} else if (!this.$props.data.errorLogPath.enabled) {
|
||||||
|
this.$props.data.errorLogPath.enabled = true;
|
||||||
|
this.$props.data.errorLogPath.computed = this.$props.data.errorLogPath.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -147,16 +147,17 @@ THE SOFTWARE.
|
||||||
<script>
|
<script>
|
||||||
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
||||||
import computedFromDefaults from '../../util/computed_from_defaults';
|
import computedFromDefaults from '../../util/computed_from_defaults';
|
||||||
|
import { serverDomainDefault } from '../../util/defaults';
|
||||||
import PrettyCheck from '../inputs/checkbox';
|
import PrettyCheck from '../inputs/checkbox';
|
||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
domain: {
|
domain: {
|
||||||
default: 'example.com',
|
default: serverDomainDefault,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
path: {
|
path: {
|
||||||
default: '',
|
default: '',
|
||||||
computed: '/var/www/example.com', // No default value, but a default computed
|
computed: `/var/www/${serverDomainDefault}`, // No default value, but a default computed
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
documentRoot: {
|
documentRoot: {
|
||||||
|
|
|
@ -26,37 +26,46 @@ THE SOFTWARE.
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="field is-horizontal">
|
<div class="field is-horizontal is-aligned-top">
|
||||||
<div class="field-label">
|
<div class="field-label has-small-margin-top">
|
||||||
<label class="label">access_log</label>
|
<label class="label">error_log</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div :class="`control${accessLogChanged ? ' is-changed' : ''}`">
|
<div :class="`control${errorLogEnabledChanged ? ' is-changed' : ''}`">
|
||||||
|
<div class="checkbox">
|
||||||
|
<PrettyCheck v-model="errorLogEnabled" class="p-default p-curve p-fill p-icon">
|
||||||
|
{{ $t('common.enable') }}
|
||||||
|
</PrettyCheck>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="$props.data.errorLogEnabled.computed" :class="`control field is-horizontal is-expanded${errorLogPathChanged ? ' is-changed' : ''}`">
|
||||||
<input
|
<input
|
||||||
v-model="accessLog"
|
v-model="errorLogPath"
|
||||||
class="input"
|
class="input"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$props.data.accessLog.default"
|
:placeholder="$props.data.errorLogPath.default"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
<div v-if="$props.data.errorLogEnabled.computed" class="field is-horizontal">
|
||||||
<div class="field-label">
|
<div class="field-label">
|
||||||
<label class="label">error_log</label>
|
<label class="label">error_log {{ $t('templates.globalSections.logging.level') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field">
|
<div class="field is-horizontal">
|
||||||
<div :class="`control${errorLogChanged ? ' is-changed' : ''}`">
|
<div
|
||||||
<input
|
v-for="value in $props.data.errorLogLevel.options"
|
||||||
v-model="errorLog"
|
:class="`control${errorLogLevelChanged && value === errorLogLevel ? ' is-changed' : ''}`"
|
||||||
class="input"
|
>
|
||||||
type="text"
|
<div class="radio">
|
||||||
:placeholder="$props.data.errorLog.default"
|
<PrettyRadio v-model="errorLogLevel" :value="value" class="p-default p-round p-fill p-icon">
|
||||||
/>
|
{{ value }}
|
||||||
|
</PrettyRadio>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -157,15 +166,22 @@ THE SOFTWARE.
|
||||||
<script>
|
<script>
|
||||||
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
import delegatedFromDefaults from '../../util/delegated_from_defaults';
|
||||||
import computedFromDefaults from '../../util/computed_from_defaults';
|
import computedFromDefaults from '../../util/computed_from_defaults';
|
||||||
|
import { errorLogPathDefault, errorLogLevelDefault, errorLogLevelOptions } from '../../util/logging';
|
||||||
import PrettyCheck from '../inputs/checkbox';
|
import PrettyCheck from '../inputs/checkbox';
|
||||||
|
import PrettyRadio from '../inputs/radio';
|
||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
accessLog: {
|
errorLogEnabled: {
|
||||||
default: '/var/log/nginx/access.log',
|
default: false,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
errorLog: {
|
errorLogPath: {
|
||||||
default: '/var/log/nginx/error.log warn',
|
default: errorLogPathDefault,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
errorLogLevel: {
|
||||||
|
default: errorLogLevelDefault,
|
||||||
|
options: errorLogLevelOptions,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
logNotFound: {
|
logNotFound: {
|
||||||
|
@ -217,6 +233,7 @@ THE SOFTWARE.
|
||||||
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
|
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
|
||||||
components: {
|
components: {
|
||||||
PrettyCheck,
|
PrettyCheck,
|
||||||
|
PrettyRadio,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
data: Object, // Data delegated back to us from parent
|
data: Object, // Data delegated back to us from parent
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,10 +24,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getAccessLogDomainPath = (domain, global) => {
|
export const serverDomainDefault = 'example.com';
|
||||||
return global.logging.accessLog.computed.replace(/([^/]+)\.log$/, `${domain.server.domain.computed}.$1.log`);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getErrorLogDomainPath = (domain, global) => {
|
|
||||||
return global.logging.errorLog.computed.replace(/([^/]+)\.log (.+)$/, `${domain.server.domain.computed}.$1.log $2`);
|
|
||||||
};
|
|
55
src/nginxconfig/util/logging.js
Normal file
55
src/nginxconfig/util/logging.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
|
This code is licensed under the MIT License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const accessLogPathDefault = '/var/log/nginx/access.log';
|
||||||
|
export const accessLogParamsDefault = 'buffer=512k flush=1m';
|
||||||
|
|
||||||
|
export const errorLogPathDefault = '/var/log/nginx/error.log';
|
||||||
|
export const errorLogPathDisabled = '/dev/null';
|
||||||
|
export const errorLogLevelDefault = 'warn';
|
||||||
|
export const errorLogLevelOptions = Object.freeze(['debug', 'info', 'notice', 'warn', 'error', 'crit', 'alert', 'emerg']);
|
||||||
|
export const errorLogLevelDisabled = 'none';
|
||||||
|
|
||||||
|
export const getDomainAccessLog = (domain, global) => {
|
||||||
|
let path = domain.logging.accessLogPath.computed.trim();
|
||||||
|
if (!path) {
|
||||||
|
path = accessLogPathDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path +
|
||||||
|
(global.logging.cloudflare.computed ? ' cloudflare' : '') +
|
||||||
|
(domain.logging.accessLogParameters.computed.trim() ? ` ${domain.logging.accessLogParameters.computed.trim()}`: '');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDomainErrorLog = (domain) => {
|
||||||
|
let path = domain.logging.errorLogPath.computed.trim();
|
||||||
|
if (!path) {
|
||||||
|
path = errorLogPathDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorLogLevel = errorLogLevelOptions.includes(domain.logging.errorLogLevel.computed) ? ` ${domain.logging.errorLogLevel.computed}` : '';
|
||||||
|
return `${path}${errorLogLevel}`;
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -26,6 +26,71 @@ THE SOFTWARE.
|
||||||
|
|
||||||
import isObject from './is_object';
|
import isObject from './is_object';
|
||||||
import deepMerge from './deep_merge';
|
import deepMerge from './deep_merge';
|
||||||
|
import { accessLogPathDefault, accessLogParamsDefault, errorLogPathDefault, errorLogPathDisabled, errorLogLevelDefault } from './logging';
|
||||||
|
import { serverDomainDefault } from './defaults';
|
||||||
|
|
||||||
|
// Migrate old logging settings to new ones
|
||||||
|
const migrateLogging = data => {
|
||||||
|
if (Object.keys(data).length === 0) return;
|
||||||
|
|
||||||
|
const globalLogging = 'logging' in data.global && isObject(data.global.logging) ? data.global.logging : {};
|
||||||
|
|
||||||
|
// global access_log
|
||||||
|
const [globalAccessLogPath, ...globalAccessLogParameters] = (globalLogging.accessLog || accessLogPathDefault).split(' ');
|
||||||
|
const globalAccessLogEnabled =
|
||||||
|
!('accessLog' in globalLogging) || // accessLog was enabled by default and might not appear at all
|
||||||
|
(globalAccessLogPath !== '' && globalAccessLogPath !== 'off'); // *or* someone turned it off explicitly
|
||||||
|
|
||||||
|
// global error_log
|
||||||
|
const [globalErrorLogPath, ...globalErrorLogLevel] = (globalLogging.errorLog || `${errorLogPathDefault} ${errorLogLevelDefault}`).split(' ');
|
||||||
|
const globalErrorLogEnabled =
|
||||||
|
!('errorLog' in globalLogging) || // errorLog was enabled by default and might not appear at all
|
||||||
|
(globalErrorLogPath !== '' && globalErrorLogPath !== errorLogPathDisabled); // *or* someone turned it off explicitly
|
||||||
|
|
||||||
|
// set global access_log / error_log files for every domain UNLESS it was explicitly
|
||||||
|
// enabled for the domain
|
||||||
|
for (const key in data.domains) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(data.domains, key)) continue;
|
||||||
|
|
||||||
|
const perDomainServer = {
|
||||||
|
domain: serverDomainDefault,
|
||||||
|
...('server' in data.domains[key] && isObject(data.domains[key].server) ? data.domains[key].server : {}),
|
||||||
|
};
|
||||||
|
const perDomainLogging = 'logging' in data.domains[key] && isObject(data.domains[key].logging) ? data.domains[key].logging : {};
|
||||||
|
|
||||||
|
// access_log
|
||||||
|
let accessLogEnabled = globalAccessLogEnabled,
|
||||||
|
accessLogPath = globalAccessLogPath;
|
||||||
|
const accessLogParameters = globalAccessLogParameters.join(' ') || accessLogParamsDefault;
|
||||||
|
|
||||||
|
const perDomainAccessLogEnabled = !!perDomainLogging.accessLog;
|
||||||
|
if (perDomainAccessLogEnabled) {
|
||||||
|
accessLogEnabled = true;
|
||||||
|
accessLogPath = accessLogPath.replace(/([^/]+)\.log$/, `${perDomainServer.domain}.$1.log`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// error_log
|
||||||
|
let errorLogEnabled = globalErrorLogEnabled,
|
||||||
|
errorLogPath = globalErrorLogPath;
|
||||||
|
const errorLogLevel = globalErrorLogLevel.join(' ') || errorLogLevelDefault;
|
||||||
|
|
||||||
|
const perDomainErrorLogEnabled = !!perDomainLogging.errorLog;
|
||||||
|
if (perDomainErrorLogEnabled) {
|
||||||
|
errorLogEnabled = true;
|
||||||
|
errorLogPath = errorLogPath.replace(/([^/]+)\.log$/, `${perDomainServer.domain}.$1.log`);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.domains[key].logging = {
|
||||||
|
accessLogEnabled,
|
||||||
|
accessLogPath,
|
||||||
|
accessLogParameters,
|
||||||
|
errorLogEnabled,
|
||||||
|
errorLogPath,
|
||||||
|
errorLogLevel,
|
||||||
|
...perDomainLogging,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Handle converting the old query format to our new query params
|
// Handle converting the old query format to our new query params
|
||||||
export default data => {
|
export default data => {
|
||||||
|
@ -68,4 +133,6 @@ export default data => {
|
||||||
deepMerge(data.domains[key], mappedData);
|
deepMerge(data.domains[key], mappedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
migrateLogging(data);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue