Skip to content
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

Allow a user-provided logger for Server, Gateway and AER #3894

Merged
merged 19 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c4baaec
Switch multi-argument `logger` pattern to single parameter invocations.
abernix Mar 10, 2020
8a19ecc
Decompose `GatewayConfigBase` into types in preparation for `logger`.
abernix Mar 10, 2020
780d7f4
gateway: Introduce `Logger` type and expose on `logger` config.
abernix Mar 10, 2020
39913c3
tests: test various popular loggers: log4js, winston, bunyan, loglevel.
abernix Mar 10, 2020
ff20305
Add optional `logger` to `GraphQLServiceContext` and `GraphQLRequestC…
abernix Mar 13, 2020
a9f1d67
Introduce optional `logger` property for `apollo-engine-reporting`.
abernix Mar 13, 2020
eadcc6b
Introduce optional `logger` for `ApolloServer` class.
abernix Mar 13, 2020
0929c2f
To support Node.js 6, use older version of `log4js` for testing.
abernix Mar 16, 2020
2d43a74
ResponseCache: when available, use `requestContext.logger` to log.
abernix Mar 13, 2020
827a1b4
gateway: when set, log using `requestContext.logger` in `executeQuery…
abernix Mar 13, 2020
80a12d8
Make `logger` required on `GraphQLServiceContext` + `GraphQLRequestCo…
abernix Mar 13, 2020
fea6f15
Fix all the spelling mistakes.
abernix Mar 17, 2020
88c8ee8
Merge remote-tracking branch 'origin/release-2.12.0' into abernix/log…
abernix Mar 17, 2020
2461e98
Add CHANGELOG for #3894.
abernix Mar 17, 2020
6a5402f
docs: Explain `logger` on `ApolloServer` and `EngineReportingOptions`.
abernix Mar 17, 2020
f6ba2de
Kinda revert "Decompose `GatewayConfigBase` into types in prep..."
abernix Mar 17, 2020
603608d
docs: Explain `logger` on `ApolloGateway` in the API reference.
abernix Mar 17, 2020
fefe7ff
Apply counter-intuitive severity to `debugPrintReports` messages.
abernix Mar 17, 2020
b32e1d1
docs: Note presence of `logger` in plugins' lifecycle hooks.
abernix Mar 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ The version headers in this history reflect the versions of Apollo Server itself
- [__CHANGELOG for `@apollo/gateway`__](https://github.com/apollographql/apollo-server/blob/master/packages/apollo-gateway/CHANGELOG.md)
- [__CHANGELOG for `@apollo/federation`__](https://github.com/apollographql/apollo-server/blob/master/packages/apollo-federation/CHANGELOG.md)

### v2.13.0

- `apollo-server-core`: Support providing a custom logger implementation (e.g. [`winston`](https://npm.im/winston), [`bunyan`](https://npm.im/bunyan), etc.) to capture server console messages. Though there has historically been limited output from Apollo Server, some messages are important to capture in the larger context of production logging facilities or can benefit from using more advanced structure, like JSON-based logging. This also introduces a `logger` property to the `GraphQLRequestContext` that is exposed to plugins, making it possible for plugins to leverage the same server-level logger, and allowing implementors to create request-specific log contexts, if desired. When not provided, these will still output to `console`. [PR #3894](https://github.com/apollographql/apollo-server/pull/3894)

### v2.12.0

- `apollo-server-core`: When operating in gateway mode using the `gateway` property of the Apollo Server constructor options, the failure to initialize a schema during initial start-up, e.g. connectivity problems, will no longer result in the federated executor from being assigned when the schema eventually becomes available. This precludes a state where the gateway may never become available to serve federated requests, even when failure conditions are no longer present. [PR #3811](https://github.com/apollographql/apollo-server/pull/3811)
Expand Down
11 changes: 9 additions & 2 deletions docs/source/api/apollo-gateway.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,20 @@ example of using `ApolloGateway`, see [The gateway](/federation/gateway/).
});
```

* `logger`: `Logger`

A logging implementation to be used in place of `console`. The implementation must provide the methods which satisfy the requirements of [the `Logger` interface](https://github.com/apollographql/apollo-server/blob/80a12d89ea1ae9a0892f4a81d9213eddf95ca965/packages/apollo-server-types/src/index.ts#L114-L121) (i.e. it must provide `debug`, `info`, `warn` and `error` methods). When a custom logger is provided, it will receive all levels of logging and it is up to the logger itself to determine how it wishes to handle each level. When a custom logger is _not_ provided, Gateway will default to outputting `warn` and `error` levels unless `debug: true` is specified, in which case it will output all log levels (i.e. `debug` through `error`).

Additionally, this `logger` will be made available on the `GraphQLRequestContext` and available to plugins. This allows a plugin to, e.g., augment the logger on a per-request basis within the `requestDidStart` life-cycle hook.


* `debug`: `Boolean`

If `true`, the gateway logs startup messages, along with the query plan for
each incoming request. The default value is `false`.

* `fetcher`: `typeof fetch`

When specified, overrides the default
[Fetch API](https://fetch.spec.whatwg.org/#fetch-api) implementation
which is used when communicating with downstream services. By default,
Expand Down
10 changes: 10 additions & 0 deletions docs/source/api/apollo-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ new ApolloServer({
| AWS Lambda | <code>{<br/>&nbsp;&nbsp;event: [`APIGatewayProxyEvent`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/50adc95acf873e714256074311353232fcc1b5ed/types/aws-lambda/index.d.ts#L78-L92),<br/>&nbsp;&nbsp;context: [`LambdaContext`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/50adc95acf873e714256074311353232fcc1b5ed/types/aws-lambda/index.d.ts#L510-L534)<br/>}</code> |
| Micro | <code>{ req: [`MicroRequest`](https://github.com/apollographql/apollo-server/blob/c356bcf3f2864b8d2fcca0add455071e0606ef46/packages/apollo-server-micro/src/types.ts#L3-L5), res: [`ServerResponse`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/50adc95acf873e714256074311353232fcc1b5ed/types/node/v10/http.d.ts#L145-L158) }</code> |

* `logger`: `Logger`

A logging implementation to be used in place of `console`. The implementation must provide the methods which satisfy the requirements of [the `Logger` interface](https://github.com/apollographql/apollo-server/blob/80a12d89ea1ae9a0892f4a81d9213eddf95ca965/packages/apollo-server-types/src/index.ts#L114-L121) (i.e. it must provide `debug`, `info`, `warn` and `error` methods). When a custom logger is provided, it will receive all levels of logging and it is up to the logger itself to determine how it wishes to handle each level. When a custom logger is _not_ provided, Apollo Server will default to outputting `warn` and `error` levels unless `debug: true` is specified, in which case it will output all log levels (i.e. `debug` through `error`).

Additionally, this `logger` will be made available on the `GraphQLRequestContext` and available to plugins. This allows a plugin to, e.g., augment the logger on a per-request basis within the `requestDidStart` life-cycle hook.

* `rootValue`: <`Any`> | <`Function`>

A value or function called with the parsed `Document`, creating the root value passed to the graphql executor. The function is useful if you wish to provide a different root value based on the query operation type.
Expand Down Expand Up @@ -337,6 +343,10 @@ addMockFunctionsToSchema({
a service. You can also specify an API key with the `ENGINE_API_KEY`
environment variable, although the `apiKey` option takes precedence.

* `logger`: `Logger`

By default, this will inherit from the `logger` provided to `ApolloServer` which defaults to `console` when not provided. If specified within the `EngineReportingOptions` it can be used to send engine reporting to a separate logger. If provided, the implementation must provide the methods which satisfy the requirements of [the `Logger` interface](https://github.com/apollographql/apollo-server/blob/80a12d89ea1ae9a0892f4a81d9213eddf95ca965/packages/apollo-server-types/src/index.ts#L114-L121) (i.e. it must provide `debug`, `info`, `warn` and `error` methods).

* `calculateSignature`: (ast: DocumentNode, operationName: string) => string

Specify the function for creating a signature for a query.
Expand Down
23 changes: 16 additions & 7 deletions docs/source/integrations/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,15 @@ const server = new ApolloServer({

The `requestDidStart` event fires whenever Apollo Server begins fulfilling a GraphQL request.

```typescript
requestDidStart?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'request' | 'context' | 'logger'
>
): GraphQLRequestListener<TContext> | void;
```

This function can optionally return an object that includes functions for responding
to request lifecycle events that might follow `requestDidStart`.

Expand Down Expand Up @@ -318,7 +327,7 @@ does not occur.
parsingDidStart?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source'
'metrics' | 'source' | 'logger'
>,
): (err?: Error) => void | void;
```
Expand All @@ -338,7 +347,7 @@ available at this stage, because parsing must succeed for validation to occur.
validationDidStart?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source' | 'document'
'metrics' | 'source' | 'document' | 'logger'
>,
): (err?: ReadonlyArray<Error>) => void | void;
```
Expand All @@ -355,7 +364,7 @@ both the `operationName` string and `operation` AST are available.
didResolveOperation?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source' | 'document' | 'operationName' | 'operation'
'metrics' | 'source' | 'document' | 'operationName' | 'operation' | 'logger'
>,
): ValueOrPromise<void>;
```
Expand All @@ -371,7 +380,7 @@ are invoked in series, and the first non-null response is used.
responseForOperation?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source' | 'document' | 'operationName' | 'operation'
'metrics' | 'source' | 'document' | 'operationName' | 'operation' | 'logger'
>,
): ValueOrPromise<GraphQLResponse | null>;
```
Expand All @@ -385,7 +394,7 @@ GraphQL operation specified by a request's `document` AST.
executionDidStart?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source' | 'document' | 'operationName' | 'operation'
'metrics' | 'source' | 'document' | 'operationName' | 'operation' | 'logger'
>,
): (err?: Error) => void | void;
```
Expand All @@ -399,7 +408,7 @@ parsing, validating, or executing a GraphQL operation.
didEncounterErrors?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'source' | 'errors'
'metrics' | 'source' | 'errors' | 'logger'
>,
): ValueOrPromise<void>;
```
Expand All @@ -414,7 +423,7 @@ if the GraphQL operation encounters one or more errors.
willSendResponse?(
requestContext: WithRequired<
GraphQLRequestContext<TContext>,
'metrics' | 'response'
'metrics' | 'response' | 'logger'
>,
): ValueOrPromise<void>;
```
Loading