-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.js
113 lines (94 loc) · 3.15 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
Copyright © 2019 Andrew Powell
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of this Source Code Form.
*/
const chalk = require('chalk');
const { print } = require('graphql');
const loglevel = require('loglevelnext');
const colors = {
trace: 'cyan',
debug: 'magenta',
info: 'blue',
warn: 'yellow',
error: 'red'
};
const defaults = {
level: 'info',
mutate: (level, data) => {}, // eslint-disable-line no-unused-vars
prefix: 'apollo: ',
timestamp: false
};
class ApolloLogExtension {
constructor(options) {
const opts = Object.assign({}, defaults, options);
const template = `${opts.timestamp ? '[{{time}}] ' : ''}{{level}}`;
const prefix = {
level: ({ level }) => {
const color = colors[level];
return chalk[color](opts.prefix);
},
template,
time: () => new Date().toTimeString().split(' ')[0]
};
const log = loglevel.create({ level: opts.level, name: 'apollo-log', prefix });
this.log = {
info: (args) => {
const mutated = opts.mutate(...['info'].concat(args));
log.info(mutated || args);
},
debug: (args) => {
const mutated = opts.mutate(...['debug'].concat(args));
log.debug(mutated || args);
}
};
this.options = opts;
}
requestDidStart({ operationName, parsedQuery, queryString, request, variables }) {
const query = queryString || print(parsedQuery);
const { method, redirect, headers, parsedURL, signal } = request;
const rawHeaders = headers.raw();
for (const key of Object.keys(rawHeaders)) {
const value = rawHeaders[key];
rawHeaders[key] = value && value.length > 1 ? value : value[0];
}
this.log.info({ action: 'request', status: 'begin', operationName, query, variables });
this.log.info({
action: 'request',
status: 'data',
request: { method, redirect, headers: rawHeaders, parsedURL, signal }
});
return (...errors) => {
if (errors.length) {
this.log.error({ action: 'request', status: 'failed', errors }, '\n');
}
};
}
parsingDidStart({ queryString }) {
this.log.debug({ action: 'parse', status: 'begin', queryString });
return () => {
this.log.debug({ action: 'parse', status: 'end', queryString });
};
}
validationDidStart() {
this.log.debug({ action: 'validation', status: 'begin' });
return () => {
this.log.debug({ action: 'validation', status: 'end' });
};
}
executionDidStart(/* { executionArgs } */) {
this.log.debug({ action: 'execute', status: 'begin' });
return () => {
this.log.debug({ action: 'execute', status: 'end' });
};
}
willSendResponse({ graphqlResponse: response }) {
const { data } = response;
this.log.info({ action: 'response', status: 'data', data });
this.log.info({ action: 'request', status: 'end', response }, '\n');
}
}
module.exports = { ApolloLogExtension };