-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support configuration reloads for logging #6720
Merged
+190
−67
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b7dbfb9
[logging] Support configuration reloads for logging. Fixes #4407.
bevacqua 4759daa
[test] Add tests for SIGHUP logging configuration reload signal.
bevacqua f09b374
[test/fix] Improved test case for logging configuration reloads.
bevacqua b73638b
[test] Safeguard against possible exceptions, errors, and misbehaving…
bevacqua 7665d5a
[rename] Renamed plugin needs updated references.
bevacqua 8df5ecf
[merge] Merge with master.
bevacqua b8d6c8c
[test] Bypass static asset optimizer and log errors more verbosely.
bevacqua 59981ba
[dep] Bump even-better to 7.0.2 fixing potential memory leak issues.
bevacqua File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/cli/serve/__tests__/fixtures/reload_logging_config/kibana.test.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
server: | ||
port: 8274 | ||
logging: | ||
json: true | ||
optimize: | ||
enabled: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { spawn } from 'child_process'; | ||
import { writeFileSync, readFile } from 'fs'; | ||
import { relative, resolve } from 'path'; | ||
import { safeDump } from 'js-yaml'; | ||
import es from 'event-stream'; | ||
import readYamlConfig from '../read_yaml_config'; | ||
import expect from 'expect.js'; | ||
const testConfigFile = follow(`fixtures/reload_logging_config/kibana.test.yml`); | ||
const cli = follow(`../../../../bin/kibana`); | ||
|
||
function follow(file) { | ||
return relative(process.cwd(), resolve(__dirname, file)); | ||
} | ||
|
||
function setLoggingJson(enabled) { | ||
const conf = readYamlConfig(testConfigFile); | ||
conf.logging = conf.logging || {}; | ||
conf.logging.json = enabled; | ||
const yaml = safeDump(conf); | ||
writeFileSync(testConfigFile, yaml); | ||
return conf; | ||
} | ||
|
||
describe(`Server logging configuration`, function () { | ||
it(`should be reloadable via SIGHUP process signaling`, function (done) { | ||
let asserted = false; | ||
let json = Infinity; | ||
const conf = setLoggingJson(true); | ||
const child = spawn(cli, [`--config`, testConfigFile]); | ||
|
||
child.on('error', err => { | ||
done(new Error(`error in child process while attempting to reload config. | ||
${err.stack || err.message || err}`)); | ||
}); | ||
|
||
child.on('exit', code => { | ||
expect(asserted).to.eql(true); | ||
expect(code === null || code === 0).to.eql(true); | ||
done(); | ||
}); | ||
|
||
child.stdout | ||
.pipe(es.split()) | ||
.pipe(es.mapSync(function (line) { | ||
if (!line) { | ||
return line; // ignore empty lines | ||
} | ||
if (json--) { | ||
expect(parseJsonLogLine).withArgs(line).to.not.throwError(); | ||
} else { | ||
expectPlainTextLogLine(line); | ||
} | ||
})); | ||
|
||
function parseJsonLogLine(line) { | ||
try { | ||
const data = JSON.parse(line); | ||
const listening = data.tags.indexOf(`listening`) !== -1; | ||
if (listening) { | ||
switchToPlainTextLog(); | ||
} | ||
} catch (err) { | ||
expect(`Error parsing log line as JSON\n | ||
${err.stack || err.message || err}`).to.eql(true); | ||
} | ||
} | ||
|
||
function switchToPlainTextLog() { | ||
json = 2; // ignore both "reloading" messages | ||
setLoggingJson(false); | ||
child.kill(`SIGHUP`); // reload logging config | ||
} | ||
|
||
function expectPlainTextLogLine(line) { | ||
// assert | ||
const tags = `[\u001b[32minfo\u001b[39m][\u001b[36mconfig\u001b[39m]`; | ||
const status = `Reloaded logging configuration due to SIGHUP.`; | ||
const expected = `${tags} ${status}`; | ||
const actual = line.slice(-expected.length); | ||
expect(actual).to.eql(expected); | ||
|
||
// cleanup | ||
asserted = true; | ||
setLoggingJson(true); | ||
child.kill(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import _ from 'lodash'; | ||
import logReporter from './log_reporter'; | ||
|
||
export default function loggingConfiguration(config) { | ||
let events = config.get('logging.events'); | ||
|
||
if (config.get('logging.silent')) { | ||
_.defaults(events, {}); | ||
} | ||
else if (config.get('logging.quiet')) { | ||
_.defaults(events, { | ||
log: ['listening', 'error', 'fatal'], | ||
request: ['error'], | ||
error: '*' | ||
}); | ||
} | ||
else if (config.get('logging.verbose')) { | ||
_.defaults(events, { | ||
log: '*', | ||
ops: '*', | ||
request: '*', | ||
response: '*', | ||
error: '*' | ||
}); | ||
} | ||
else { | ||
_.defaults(events, { | ||
log: ['info', 'warning', 'error', 'fatal'], | ||
response: config.get('logging.json') ? '*' : '!', | ||
request: ['info', 'warning', 'error', 'fatal'], | ||
error: '*' | ||
}); | ||
} | ||
|
||
const options = { | ||
opsInterval: config.get('ops.interval'), | ||
requestHeaders: true, | ||
requestPayload: true, | ||
reporters: [ | ||
{ | ||
reporter: logReporter, | ||
config: { | ||
json: config.get('logging.json'), | ||
dest: config.get('logging.dest'), | ||
// I'm adding the default here because if you add another filter | ||
// using the commandline it will remove authorization. I want users | ||
// to have to explicitly set --logging.filter.authorization=none to | ||
// have it show up int he logs. | ||
filter: _.defaults(config.get('logging.filter'), { | ||
authorization: 'remove' | ||
}) | ||
}, | ||
events: _.transform(events, function (filtered, val, key) { | ||
// provide a string compatible way to remove events | ||
if (val !== '!') filtered[key] = val; | ||
}, {}) | ||
} | ||
] | ||
}; | ||
return options; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,15 @@ | ||
import _ from 'lodash'; | ||
import { fromNode } from 'bluebird'; | ||
import evenBetter from 'even-better'; | ||
import loggingConfiguration from './configuration'; | ||
|
||
module.exports = function (kbnServer, server, config) { | ||
export default function (kbnServer, server, config) { | ||
// prevent relying on kbnServer so this can be used with other hapi servers | ||
kbnServer = null; | ||
|
||
return fromNode(function (cb) { | ||
let events = config.get('logging.events'); | ||
|
||
if (config.get('logging.silent')) { | ||
_.defaults(events, {}); | ||
} | ||
else if (config.get('logging.quiet')) { | ||
_.defaults(events, { | ||
log: ['listening', 'error', 'fatal'], | ||
request: ['error'], | ||
error: '*' | ||
}); | ||
} | ||
else if (config.get('logging.verbose')) { | ||
_.defaults(events, { | ||
log: '*', | ||
ops: '*', | ||
request: '*', | ||
response: '*', | ||
error: '*' | ||
}); | ||
} | ||
else { | ||
_.defaults(events, { | ||
log: ['info', 'warning', 'error', 'fatal'], | ||
response: config.get('logging.json') ? '*' : '!', | ||
request: ['info', 'warning', 'error', 'fatal'], | ||
error: '*' | ||
}); | ||
} | ||
|
||
server.register({ | ||
register: require('good'), | ||
options: { | ||
opsInterval: config.get('ops.interval'), | ||
requestHeaders: true, | ||
requestPayload: true, | ||
reporters: [ | ||
{ | ||
reporter: require('./log_reporter'), | ||
config: { | ||
json: config.get('logging.json'), | ||
dest: config.get('logging.dest'), | ||
// I'm adding the default here because if you add another filter | ||
// using the commandline it will remove authorization. I want users | ||
// to have to explicitly set --logging.filter.authorization=none to | ||
// have it show up int he logs. | ||
filter: _.defaults(config.get('logging.filter'), { | ||
authorization: 'remove' | ||
}) | ||
}, | ||
events: _.transform(events, function (filtered, val, key) { | ||
// provide a string compatible way to remove events | ||
if (val !== '!') filtered[key] = val; | ||
}, {}) | ||
} | ||
] | ||
} | ||
register: evenBetter, | ||
options: loggingConfiguration(config) | ||
}, cb); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to handle errors/success properly. This test will always succeed because the test doesn't wait for the client to close or catch assertion errors thrown in
expectPlainTextLogLine()