Skip to content

Commit

Permalink
feat: dump run/${type}_config_meta.json (#1155)
Browse files Browse the repository at this point in the history
Show who define the property of the config

Closes #1132
  • Loading branch information
popomore authored and fengmk2 committed Jul 5, 2017
1 parent b80bb14 commit 74c8a54
Show file tree
Hide file tree
Showing 24 changed files with 449 additions and 412 deletions.
1 change: 0 additions & 1 deletion .autod.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ module.exports = {
'@types/koa-router',
],
semver: [
'eslint@3',
'koa-bodyparser@2',
],
test: 'scripts',
Expand Down
12 changes: 11 additions & 1 deletion docs/source/en/basics/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,19 @@ path is an absolute path so that the application can put self developed plugins

## Configuration result

The final merged config will be dumped to `run/application_config.json`(for worker process) and `run/agent_config.json`(for agent process) when the framework starts, which can help analyzing problems.
The final merged config will be dumped to `run/application_config.json`(for worker process) and `run/agent_config.json`(for agent process) when the framework started, which can help analyzing problems.

Some fields are hidden in the config file, mainly including 2 types:

- like passwords, secret keys and other security related fields which can be configured in `config.dump.ignore` and only [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) type is accepted. See [Default Configs](https://github.com/eggjs/egg/blob/master/config/config.default.js)
- like Function, Buffer, etc. whose content converted by `JSON.stringify` will be specially large.

`run/application_config_meta.json` (for worker process)and `run/agent_config_meta.json` (for agent process) will also be dumped that show which file defines the property, see below

```json
{
"logger": {
"dir": "/path/to/config/config.default.js"
}
}
```
10 changes: 10 additions & 0 deletions docs/source/zh-cn/basics/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ path 为一个绝对路径,这样应用可以把自己写的插件直接放到
- 如密码、密钥等安全字段,这里可以通过 `config.dump.ignore` 配置,必须是 [Set] 类型,查看[默认配置](https://github.com/eggjs/egg/blob/master/config/config.default.js)
- 如函数、Buffer 等类型,`JSON.stringify` 后的内容特别大

还会生成 `run/application_config_meta.json`(worker 进程)和 `run/agent_config_meta.json`(agent 进程)文件,用来排查属性的来源,如

```json
{
"logger": {
"dir": "/path/to/config/config.default.js"
}
}
```

[Set]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
[extend]: https://github.com/justmoon/node-extend
[extend2]: https://github.com/eggjs/extend2
2 changes: 1 addition & 1 deletion lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class Application extends EggApplication {
Object.keys(confusedConfigurations).forEach(key => {
if (this.config[key] !== undefined) {
this.logger.warn('Unexpected config key `%s` exists, Please use `%s` instead.',
key, confusedConfigurations[key]);
key, confusedConfigurations[key]);
}
});
}
Expand Down
8 changes: 7 additions & 1 deletion lib/egg.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,19 @@ class EggApplication extends EggCore {
} catch (_) {
ignoreList = [];
}
const dumpFile = path.join(rundir, `${this.type}_config.json`);
try {
/* istanbul ignore if */
if (!fs.existsSync(rundir)) fs.mkdirSync(rundir);

// dump config
const json = extend(true, {}, { config: this.config, plugins: this.plugins });
utils.convertObject(json, ignoreList);
const dumpFile = path.join(rundir, `${this.type}_config.json`);
fs.writeFileSync(dumpFile, JSON.stringify(json, null, 2));

// dump config meta
const dumpMetaFile = path.join(rundir, `${this.type}_config_meta.json`);
fs.writeFileSync(dumpMetaFile, JSON.stringify(this.loader.configMeta, null, 2));
} catch (err) {
this.coreLogger.warn(`dumpConfig error: ${err.message}`);
}
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
"@types/koa-router": "^7.0.22",
"accepts": "^1.3.3",
"agentkeepalive": "^3.3.0",
"cluster-client": "^1.6.4",
"cluster-client": "^1.6.5",
"co": "^4.6.0",
"debug": "^2.6.8",
"delegates": "^1.0.0",
"egg-cluster": "^1.8.0",
"egg-cookies": "^2.2.1",
"egg-core": "^3.11.0",
"egg-core": "^3.12.0",
"egg-development": "^1.3.1",
"egg-i18n": "^1.1.1",
"egg-jsonp": "^1.1.1",
Expand All @@ -48,20 +48,20 @@
"sendmessage": "^1.1.0",
"urllib": "^2.22.0",
"utility": "^1.12.0",
"ylru": "^1.0.0"
"ylru": "^1.1.0"
},
"devDependencies": {
"autod": "^2.8.0",
"autod-egg": "^1.0.0",
"coffee": "^4.0.1",
"coffee": "^4.1.0",
"egg-alinode": "^1.0.3",
"egg-bin": "^4.0.4",
"egg-doctools": "^2.0.0",
"egg-doctools": "^2.0.1",
"egg-mock": "^3.8.0",
"egg-plugin-puml": "^2.4.0",
"egg-view-nunjucks": "^2.1.2",
"eslint": "^3.19.0",
"eslint-config-egg": "^4.2.1",
"egg-view-nunjucks": "^2.1.3",
"eslint": "^4.1.1",
"eslint-config-egg": "^5.0.0",
"findlinks": "^1.1.0",
"formstream": "^1.1.0",
"glob": "^7.1.2",
Expand Down
29 changes: 16 additions & 13 deletions test/app/extend/context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ describe('test/app/extend/context.test.js', () => {
const logdir = app.config.logger.dir;

yield app.httpRequest()
.get('/logger?message=foo')
.expect('logger');
.get('/logger?message=foo')
.expect('logger');

yield sleep(5000);

Expand Down Expand Up @@ -54,8 +54,8 @@ describe('test/app/extend/context.test.js', () => {
});

yield app.httpRequest()
.get('/logger?message=foo')
.expect('logger');
.get('/logger?message=foo')
.expect('logger');

yield sleep(5000);

Expand Down Expand Up @@ -83,8 +83,8 @@ describe('test/app/extend/context.test.js', () => {
const logdir = app.config.logger.dir;

yield app.httpRequest()
.get('/logger?message=foo')
.expect('logger');
.get('/logger?message=foo')
.expect('logger');

yield sleep(5000);

Expand Down Expand Up @@ -114,8 +114,8 @@ describe('test/app/extend/context.test.js', () => {

it('should return null when logger is not found', () => {
return app.httpRequest()
.get('/noExistLogger')
.expect('null');
.get('/noExistLogger')
.expect('null');
});

it('should log with padding message', function* () {
Expand Down Expand Up @@ -280,15 +280,16 @@ describe('test/app/extend/context.test.js', () => {

it('should curl as promise ok', () => {
return utils.startLocalServer()
.then(localServer => app.mockContext().curl(`${localServer}/foo/bar`))
.then(res => assert(res.status === 200));
.then(localServer => app.mockContext().curl(`${localServer}/foo/bar`))
.then(res => assert(res.status === 200));
});
});

describe('ctx.httpclient', () => {
it('should only one httpclient on one ctx', function* () {
const ctx = app.mockContext();
assert(ctx.httpclient === ctx.httpclient);
const httpclient = ctx.httpclient;
assert(ctx.httpclient === httpclient);
assert(typeof ctx.httpclient.request === 'function');
assert(typeof ctx.httpclient.curl === 'function');
});
Expand Down Expand Up @@ -342,7 +343,8 @@ describe('test/app/extend/context.test.js', () => {
describe('get helper()', () => {
it('should be the same helper instance', () => {
const ctx = app.mockContext();
assert(ctx.helper === ctx.helper);
const helper = ctx.helper;
assert(ctx.helper === helper);
});
});

Expand All @@ -354,7 +356,8 @@ describe('test/app/extend/context.test.js', () => {

it('should return same logger instance', () => {
const ctx = app.mockContext();
assert(ctx.getLogger('coreLogger') === ctx.getLogger('coreLogger'));
const logger = ctx.getLogger('coreLogger');
assert(ctx.getLogger('coreLogger') === logger);
});
});
});
Expand Down
12 changes: 6 additions & 6 deletions test/app/extend/response.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ describe('test/app/extend/response.test.js', () => {

it('should get lower case header', () => {
return app.httpRequest()
.get('/')
.expect(200)
.expect(res => {
assert(res.res.rawHeaders.indexOf('content-type') >= 0);
assert(res.res.rawHeaders.indexOf('content-length') >= 0);
});
.get('/')
.expect(200)
.expect(res => {
assert(res.res.rawHeaders.indexOf('content-type') >= 0);
assert(res.res.rawHeaders.indexOf('content-length') >= 0);
});
});

it('should get body length', () => {
Expand Down
76 changes: 38 additions & 38 deletions test/app/middleware/body_parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ describe('test/app/middleware/body_parser.test.js', () => {
app = utils.app('apps/body_parser_testapp');
app.ready(() => {
app.httpRequest()
.get('/test/body_parser/user')
.expect(200, (err, res) => {
assert(!err);
csrf = res.body.csrf || '';
cookies = res.headers['set-cookie'].join(';');
assert(csrf);
done();
});
.get('/test/body_parser/user')
.expect(200, (err, res) => {
assert(!err);
csrf = res.body.csrf || '';
cookies = res.headers['set-cookie'].join(';');
assert(csrf);
done();
});
});
});

Expand All @@ -29,65 +29,65 @@ describe('test/app/middleware/body_parser.test.js', () => {

it('should 200 when post form body below the limit', done => {
app.httpRequest()
.post('/test/body_parser/user')
.set('Cookie', cookies)
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('Accept', 'application/json')
.post('/test/body_parser/user')
.set('Cookie', cookies)
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('Accept', 'application/json')
// https://snyk.io/vuln/npm:qs:20170213 test case
.send(querystring.stringify({ foo: 'bar', _csrf: csrf, ']': 'toString' }))
.expect({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect(200, done);
.send(querystring.stringify({ foo: 'bar', _csrf: csrf, ']': 'toString' }))
.expect({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect(200, done);
});

it('should 200 when post json body below the limit', done => {
app.httpRequest()
.post('/test/body_parser/user')
.set('Cookie', cookies)
.set('Content-Type', 'application/json')
.send({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect(200, done);
.post('/test/body_parser/user')
.set('Cookie', cookies)
.set('Content-Type', 'application/json')
.send({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect({ foo: 'bar', _csrf: csrf, ']': 'toString' })
.expect(200, done);
});

it('should disable body parser', function* () {
app1 = utils.app('apps/body_parser_testapp_disable');
yield app1.ready();

yield app1.httpRequest()
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);
});

it('should body parser support ignore', function* () {
app1 = utils.app('apps/body_parser_testapp_ignore');
yield app1.ready();

yield app1.httpRequest()
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);

yield app1.httpRequest()
.post('/test/body_parser/form.json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ foo: 'bar', ']': 'toString' })
.expect({ foo: 'bar', ']': 'toString' });
.post('/test/body_parser/form.json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ foo: 'bar', ']': 'toString' })
.expect({ foo: 'bar', ']': 'toString' });
});

it('should body parser support match', function* () {
app1 = utils.app('apps/body_parser_testapp_match');
yield app1.ready();

yield app1.httpRequest()
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect({ foo: 'bar', ']': 'toString' });
.post('/test/body_parser/foo.json')
.send({ foo: 'bar', ']': 'toString' })
.expect({ foo: 'bar', ']': 'toString' });

yield app1.httpRequest()
.post('/test/body_parser/form.json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);
.post('/test/body_parser/form.json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ foo: 'bar', ']': 'toString' })
.expect(204);
});
});
6 changes: 3 additions & 3 deletions test/async/_async.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ describe('test/async.test.js', () => {

it('middleware, controller and service support async functions', async () => {
await app.httpRequest()
.get('/api')
.expect(200)
.expect([ 'service', 'controller', 'router', 'middleware' ]);
.get('/api')
.expect(200)
.expect([ 'service', 'controller', 'router', 'middleware' ]);
});
});
20 changes: 10 additions & 10 deletions test/lib/agent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ describe('test/lib/agent.test.js', () => {

it('should catch exeption', done => {
app.httpRequest()
.get('/agent-throw')
.expect(200, err => {
assert(!err);
setTimeout(() => {
const body = fs.readFileSync(path.join(baseDir, 'logs/agent-throw/common-error.log'), 'utf8');
assert(body.includes('nodejs.unhandledExceptionError: agent error'));
app.notExpect(/nodejs.AgentWorkerDiedError/);
done();
}, 1000);
});
.get('/agent-throw')
.expect(200, err => {
assert(!err);
setTimeout(() => {
const body = fs.readFileSync(path.join(baseDir, 'logs/agent-throw/common-error.log'), 'utf8');
assert(body.includes('nodejs.unhandledExceptionError: agent error'));
app.notExpect(/nodejs.AgentWorkerDiedError/);
done();
}, 1000);
});
});

it('should catch uncaughtException string error', done => {
Expand Down
4 changes: 2 additions & 2 deletions test/lib/cluster/app_worker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('test/lib/cluster/app_worker.test.js', () => {

it('should start cluster success and app worker emit `server` event', () => {
return app.httpRequest()
.get('/')
.expect('true');
.get('/')
.expect('true');
});
});
Loading

0 comments on commit 74c8a54

Please sign in to comment.