Skip to content

Commit

Permalink
Move logger options to Hydrogen config (#1403)
Browse files Browse the repository at this point in the history
* Stop using globalThis for logger and minor refactor

* Move logger options to Hydrogen config file

* Update unit tests

* Remove setLogger call from e2e tests

* Always call setLogger for HMR

* Remove unnecessary type

* Add docs

* Changeset

* Fix link

* Apply suggestions from code review

Co-authored-by: Michelle Vinci <[email protected]>

Co-authored-by: Michelle Vinci <[email protected]>
  • Loading branch information
frandiox and mcvinci authored Jun 2, 2022
1 parent b01486e commit 979f817
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 228 deletions.
44 changes: 44 additions & 0 deletions .changeset/rotten-nails-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
'@shopify/hydrogen': minor
---

The `setLogger` and `setLoggerOptions` utilities have been removed. The same information can now be passed under the `logger` property in Hydrogen config:

```diff
// App.server.jsx

-import {setLogger, setLoggerOptions} from '@shopify/hydrogen';

-setLogger({
- trace() {},
- error() {},
- // ...
-});

-setLoggerOptions({
- showQueryTiming: true,
- showCacheControlHeader: true,
- // ...
-});

function App() {
// ...
}

export default renderHydrogen(App);
```

```diff
// hydrogen.config.js

export default defineConfig({
// ...
+ logger: {
+ trace() {},
+ error() {},
+ showQueryTiming: true,
+ showCacheControlHeader: true,
+ // ...
+ },
});
```
40 changes: 2 additions & 38 deletions docs/framework/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,25 +152,7 @@ export default defineConfig({

{% endcodeblock %}

To enable logging for the cache API status, call `setLoggerOptions` and set `showCacheApiStatus` to `true`:

{% codeblock file, filename: '/src/App.server.jsx' %}

```js
import renderHydrogen from '@shopify/hydrogen/entry-server';
import {setLoggerOptions} from '@shopify/hydrogen';

setLoggerOptions({showCacheApiStatus: true});

function App() {
/* ... */
}
// ...
```

{% endcodeblock %}

The status of the cache updates on each query:
To enable logging for the cache API status, set `logger.showCacheApiStatus` to `true` in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). The status of the cache updates on each query:

```sh
[Cache] MISS query shopInfo
Expand All @@ -179,25 +161,7 @@ The status of the cache updates on each query:
[Cache] MISS query Localization
```

To enable logging for cache control headers, call `setLoggerOptions` and set `showCacheControlHeader` to `true`:

{% codeblock file, filename: '/src/App.server.jsx' %}

```js
import renderHydrogen from '@shopify/hydrogen/entry-server';
import {setLoggerOptions} from '@shopify/hydrogen';

setLoggerOptions({showCacheControlHeader: true});

function App() {
/* ... */
}
// ...
```

{% endcodeblock %}

A cache control header report displays for each page request. The report includes the associated queries
To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). A cache control header report displays for each page request. The report includes the associated queries
that built the request and the cache control headers:

```sh
Expand Down
32 changes: 32 additions & 0 deletions docs/framework/hydrogen-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ The following groupings of configuration properties can exist in Hydrogen:
- [`session`](#session)
- [`serverAnalyticsConnectors`](#serveranalyticsconnectors)
- [`enableStreaming`](#enablestreaming)
- [`logger`](#logger)

### `routes`

Expand Down Expand Up @@ -209,6 +210,37 @@ export default defineConfig({
> Tip:
> There are [performance benefits](https://shopify.dev/custom-storefronts/hydrogen/best-practices/performance) to streaming. You shouldn't completely disable streaming for all of your storefront's routes.
## Logger
The default behavior of the [`log` utility](https://shopify.dev/api/hydrogen/utilities/log) maps to the global `console` object. However, you can also customize this behavior in the configuration object.
You can pass [any method](https://shopify.dev/api/hydrogen/utilities/log#methods) of the `log` utility in the `logger` object to override the default behavior. The first argument of each log method contains a `request` object if the log was called in the same context as a request. The following Boolean options are also available:
{% codeblock file, filename: 'hydrogen.config.ts' %}
```tsx
export default defineConfig({
logger: {
/* Overrides the default `log.trace` behavior. */
trace: (request, ...args) => console.log(request.url, ...args),
/* Overrides the default `log.error` behavior. */
error: (request, error) => myErrorTrackingService.send(error, {request}),
/* ... */

/* Logs the cache status of each stored entry: `PUT`, `HIT`, `MISS` or `STALE`. */
showCacheApiStatus: true,
/* Logs the cache control headers of the main document and its sub queries. */
showCacheControlHeader: true,
/* Logs the timeline of when queries are being requested, resolved, and rendered. */
showQueryTiming: true,
/* Logs warnings in your app if you're over-fetching data from the Storefront API. */
showUnusedQueryProperties: true,
}
});
```
{% endcodeblock %}
## Changing the configuration file location
If you don't want the Hydrogen configuration file located at the root of your project, then you can provide the new path to the file in the Hydrogen Vite plugin (`vite.config.js`):
Expand Down
16 changes: 2 additions & 14 deletions docs/framework/preloaded-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,9 @@ const data = fetchSync('https://my.api.com/data.json', {

## Test a preloaded query

To test a preloaded query, enable the `showQueryTiming` property in `App.server.js`. The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered.
To test a preloaded query, enable the `logger.showQueryTiming` property in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger).

{% codeblock file, filename: "App.server.js" %}

```js
import {setLoggerOptions} from '@shopify/hydrogen';
...
setLoggerOptions({
showQueryTiming: true
})
```

{% endcodeblock %}

If a query is preloaded, but isn't being used, then a warning displays in the server log:
The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered. If a query is preloaded, but isn't being used, then a warning displays in the server log:

![Shows a screenshot of preloaded query warning](/assets/custom-storefronts/hydrogen/preload-query-warning.png)

Expand Down
57 changes: 4 additions & 53 deletions docs/utilities/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ export default function Product({country = {isoCode: 'US'}, log}) {
}
```

## Arguments
## Methods

None

## Return type

Return an object with methods for logging information at different priorities:
The `log` utility exposes the following methods for logging information at different priorities:

| Log method | Description |
| ------------- | --------------------------------------------------------------------------------- |
Expand All @@ -38,52 +34,7 @@ Return an object with methods for logging information at different priorities:
| `log.error()` | The logging used for errors or invalid application state. |
| `log.fatal()` | The logging used just prior to the process exiting. |

## Logger options

Logger has the following Boolean options:
## Swap logger implementation and options

| Option | Description |
| --------------------------- | ------------------------------------------------------------------------------- |
| `showCacheApiStatus` | Logs the cache status of each stored entry: `PUT`, `HIT`, `MISS` or `STALE`. |
| `showCacheControlHeader` | Logs the cache control headers of the main document and its sub queries. |
| `showQueryTiming` | Logs the timeline of when queries are being requested, resolved, and rendered. |
| `showUnusedQueryProperties` | Logs warnings in your app if you're over-fetching data from the Storefront API. |
Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. You can also show debugging information for cache and queries by providing extra options. For more information, refer to [Hydrogen configuration](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger).

### Example

```js
import {setLoggerOptions} from '@shopify/hydrogen';

setLoggerOptions({
showCacheApiStatus: true,
showCacheControlHeader: true,
showQueryTiming: true,
showUnusedQueryProperties: true,
});
```

## Swap logger implementation

Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. You can call `setLogger` with your own implementation. The first argument of each log method will contain a `request` object if the log was called in the same context as a request:

```js
import {setLogger} from '@shopify/hydrogen';

setLogger({
trace(request, ...args) {
// Call your own logger.
},
debug(request, ...args) {
// Call your own logger.
},
warn(request, ...args) {
// Call your own logger.
},
error(request, ...args) {
// Call your own logger.
},
fatal(request, ...args) {
// Call your own logger.
},
});
```
6 changes: 4 additions & 2 deletions packages/hydrogen/src/entry-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
} from './streaming.server';
import {RSC_PATHNAME, EVENT_PATHNAME, EVENT_PATHNAME_REGEX} from './constants';
import {stripScriptsFromTemplate} from './utilities/template';
import {RenderType} from './utilities/log/log';
import {setLogger, RenderType} from './utilities/log/log';
import {Analytics} from './foundation/Analytics/Analytics.server';
import {ServerAnalyticsRoute} from './foundation/Analytics/ServerAnalyticsRoute.server';
import {getSyncSessionApi} from './foundation/session/session';
Expand Down Expand Up @@ -112,8 +112,10 @@ export const renderHydrogen = (App: any) => {
request.ctx.hydrogenConfig = hydrogenConfig;
request.ctx.buyerIpHeader = buyerIpHeader;

const response = new ServerComponentResponse();
setLogger(hydrogenConfig.logger);
const log = getLoggerWithContext(request);

const response = new ServerComponentResponse();
const sessionApi = hydrogenConfig.session
? hydrogenConfig.session(log)
: undefined;
Expand Down
2 changes: 1 addition & 1 deletion packages/hydrogen/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export * from './foundation/useServerProps';
export {FileRoutes} from './foundation/FileRoutes/FileRoutes.server';
export {Route} from './foundation/Route/Route.server';
export {Router} from './foundation/Router/Router.server';
export {log, setLogger, setLoggerOptions, Logger} from './utilities/log';
export {log, type Logger} from './utilities/log';
export {LocalizationProvider} from './components/LocalizationProvider/LocalizationProvider.server';
export {ShopifyProvider} from './foundation/ShopifyProvider/ShopifyProvider.server';
export {
Expand Down
3 changes: 2 additions & 1 deletion packages/hydrogen/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ServerResponse} from 'http';
import type {Logger} from './utilities/log/log';
import type {Logger, LoggerConfig} from './utilities/log/log';
import type {ServerComponentRequest} from './framework/Hydration/ServerComponentRequest.server';
import type {ServerComponentResponse} from './framework/Hydration/ServerComponentResponse.server';
import type {
Expand Down Expand Up @@ -84,6 +84,7 @@ export type InlineHydrogenConfig = {
routes?: InlineHydrogenRoutes;
shopify?: ShopifyConfig | ShopifyConfigFetcher;
serverAnalyticsConnectors?: Array<ServerAnalyticsConnector>;
logger?: LoggerConfig;
session?: (log: Logger) => SessionStorageAdapter;
enableStreaming?: (request: ServerComponentRequest) => boolean;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
Logger,
setLogger,
logCacheApiStatus,
resetLogger,
setLoggerOptions,
} from '../index';
import {Logger, setLogger, logCacheApiStatus} from '../index';

let mockLogger: jest.Mocked<Logger>;

Expand All @@ -19,14 +13,11 @@ describe('cache header log', () => {
options: jest.fn(() => ({})),
};

setLogger(mockLogger);
setLoggerOptions({
showCacheApiStatus: true,
});
setLogger({...mockLogger, showCacheApiStatus: true});
});

afterEach(() => {
resetLogger();
setLogger(undefined);
});

it('should log cache api status', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
setLogger,
logCacheControlHeaders,
collectQueryCacheControlHeaders,
resetLogger,
setLoggerOptions,
} from '../index';
import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server';
import {ServerComponentResponse} from '../../../framework/Hydration/ServerComponentResponse.server';
Expand All @@ -26,14 +24,11 @@ describe('cache header log', () => {
options: jest.fn(() => ({})),
};

setLogger(mockLogger);
setLoggerOptions({
showCacheControlHeader: true,
});
setLogger({...mockLogger, showCacheControlHeader: true});
});

afterEach(() => {
resetLogger();
setLogger(undefined);
});

it('should log cache control header for main request', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server';
import {Logger, setLogger, resetLogger, setLoggerOptions} from '../index';
import {Logger, setLogger} from '../log';
import {collectQueryTimings, logQueryTimings} from '../log-query-timeline';

let mockLogger: jest.Mocked<Logger>;
Expand Down Expand Up @@ -36,14 +36,11 @@ describe('cache header log', () => {
options: jest.fn(() => ({})),
};

setLogger(mockLogger);
setLoggerOptions({
showQueryTiming: true,
});
setLogger({...mockLogger, showQueryTiming: true});
});

afterEach(() => {
resetLogger();
setLogger(undefined);
});

it('should log query timing', () => {
Expand Down
Loading

0 comments on commit 979f817

Please sign in to comment.