Skip to content

Commit 04015ee

Browse files
feat(logging): Add logging (#316)
* feat(logging): Add logging * Add root logger. Abstraction on top of the debug module * Switch to debug@2.6.9 * Remove noLogger
1 parent 26151de commit 04015ee

File tree

10 files changed

+87
-42
lines changed

10 files changed

+87
-42
lines changed

packages/aws-appsync/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"apollo-link-http": "1.3.1",
2828
"apollo-link-retry": "2.2.5",
2929
"aws-sdk": "2.329.0",
30-
"debug": "^4.1.0",
30+
"debug": "2.6.9",
3131
"graphql": "^0.11.7",
3232
"redux": "^3.7.2",
3333
"redux-thunk": "^2.2.0",

packages/aws-appsync/src/cache/offline-cache.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
77
* KIND, express or implied. See the License for the specific language governing permissions and limitations under the License.
88
*/
9+
import { rootLogger } from "../utils";
910
import { Cache } from 'apollo-cache';
1011
import { InMemoryCache, ApolloReducerConfig, defaultDataIdFromObject, NormalizedCacheObject } from 'apollo-cache-inmemory';
11-
import { Store } from 'redux';
12+
import { Store, AnyAction, Action } from 'redux';
1213
import { DeltaSyncState, DELTASYNC_KEY } from '../deltaSync';
14+
import { ThunkAction } from 'redux-thunk';
15+
16+
const logger = rootLogger.extend('offline-cache');
1317

1418
// Offline schema keys: Do not change in a non-backwards-compatible way
1519
export const NORMALIZED_CACHE_KEY = 'appsync';
@@ -74,14 +78,14 @@ export default class MyCache extends InMemoryCache {
7478
const { [NORMALIZED_CACHE_KEY]: normCache = {}, rehydrated = false } = this.store.getState();
7579
super.restore({ ...normCache });
7680
if (rehydrated) {
77-
// console.log('Rehydrated! Cancelling subscription.');
81+
logger('Rehydrated! Cancelling subscription.');
7882
cancelSubscription();
7983
}
8084
});
8185
}
8286

8387
restore(data: NormalizedCacheObject) {
84-
this.store.dispatch(writeThunk(WRITE_CACHE_ACTION, data) as any);
88+
boundWriteCache(this.store, data);
8589

8690
super.restore(data);
8791
super.broadcastWatches();
@@ -99,14 +103,15 @@ export default class MyCache extends InMemoryCache {
99103
if (this.data && typeof (this.data as any).record === 'undefined') {
100104
// do not persist contents of a RecordingCache
101105
const data = super.extract(true);
102-
this.store.dispatch(writeThunk(WRITE_CACHE_ACTION, data) as any);
106+
boundWriteCache(this.store, data);
103107
} else {
104-
// console.log('NO DISPATCH FOR RECORDINGCACHE')
108+
logger('No dispatch for RecordingCache');
105109
}
106110
}
107111

108112
reset() {
109-
this.store.dispatch(writeThunk(WRITE_CACHE_ACTION, {}) as any);
113+
logger('Resetting cache');
114+
boundWriteCache(this.store, {});
110115

111116
return super.reset();
112117
}
@@ -118,12 +123,18 @@ export default class MyCache extends InMemoryCache {
118123
}
119124
}
120125

121-
const writeThunk = (type, payload) => (dispatch) => {
122-
dispatch({
126+
const boundWriteCache = (store: Store<OfflineCache>, data: NormalizedCacheObject) => {
127+
logger(`Dispatching ${WRITE_CACHE_ACTION}`, { data });
128+
129+
store.dispatch(writeThunk(WRITE_CACHE_ACTION, data) as any as Action);
130+
};
131+
132+
const writeThunk:
133+
(type: string, payload: any) => ThunkAction<Action, OfflineCache, null, AnyAction> =
134+
(type, payload) => (dispatch, _getState) => dispatch({
123135
type,
124136
payload,
125137
});
126-
};
127138

128139
export const reducer = () => ({
129140
[NORMALIZED_CACHE_KEY]: (state = {}, action) => {

packages/aws-appsync/src/deltaSync.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,17 @@ import AWSAppSyncClient, { OfflineCallback, SubscribeWithSyncOptions, QuerySyncO
1414
import { OfflineEffectConfig } from "./store";
1515
import { tryFunctionOrLogError, graphQLResultHasError, getMainDefinition, addTypenameToDocument } from "apollo-utilities";
1616
import { OperationVariables, MutationUpdaterFn } from "apollo-client";
17-
import { hash, getOperationFieldName } from "./utils";
17+
import { hash, getOperationFieldName, rootLogger } from "./utils";
1818
import { Observable, FetchResult } from "apollo-link";
1919
import { Subscription } from "apollo-client/util/Observable";
2020
import { DataProxy } from "apollo-cache";
21-
import debug from 'debug';
2221
import { SKIP_RETRY_KEY } from "./link/retry-link";
2322
import { DocumentNode, print, OperationDefinitionNode, FieldNode, ExecutionResult } from "graphql";
2423
import { getOpTypeFromOperationName, CacheOperationTypes, getUpdater, QueryWithVariables } from "./helpers/offline";
2524
import { boundSaveSnapshot, replaceUsingMap, EnqueuedMutationEffect, offlineEffectConfig as mutationsConfig } from "./link/offline-link";
2625
import { CONTROL_EVENTS_KEY } from "./link/subscription-handshake-link";
2726

28-
const logger = debug('aws-appsync:deltasync');
27+
const logger = rootLogger.extend('deltasync');
2928

3029
//#region Types
3130
type DeltaSyncUpdateLastSyncAction = AnyAction & {

packages/aws-appsync/src/helpers/offline.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import { ApolloClient, MutationOptions, SubscribeToMoreOptions, OperationVariabl
1212
import { DocumentNode, InputObjectTypeDefinitionNode, NamedTypeNode } from 'graphql';
1313
import AWSAppSyncClient from '../client';
1414
import { replaceUsingMap } from '../link';
15-
import { getOperationFieldName } from '../utils';
15+
import { getOperationFieldName, rootLogger } from '../utils';
16+
17+
const logger = rootLogger.extend('offline-helper');
1618

1719
export enum CacheOperationTypes {
1820
AUTO = 'auto',
@@ -298,7 +300,7 @@ const buildMutation = <T = OperationVariables>(
298300

299301
result = queryRead;
300302
} catch (err) {
301-
console.warn('Skipping query', query, err.message);
303+
logger('Skipping query', query, err.message);
302304

303305
return;
304306
}
@@ -358,7 +360,7 @@ const buildMutation = <T = OperationVariables>(
358360
try {
359361
data = proxy.readQuery({ query, variables: queryVars });
360362
} catch (err) {
361-
console.warn('Skipping query', query, err.message);
363+
logger('Skipping query', query, err.message);
362364

363365
return;
364366
}

packages/aws-appsync/src/link/offline-link.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { NORMALIZED_CACHE_KEY, METADATA_KEY } from "../cache";
1717
import { AWSAppsyncGraphQLError } from "../types";
1818
import { Store } from "redux";
1919
import { OfflineCache, AppSyncMetadataState } from "../cache/offline-cache";
20-
import { isUuid, getOperationFieldName } from "../utils";
20+
import { isUuid, getOperationFieldName, rootLogger } from "../utils";
2121
import AWSAppSyncClient from "..";
2222
import { ApolloCache } from "apollo-cache";
2323
import { MutationUpdaterFn, MutationQueryReducersMap, ApolloError } from "apollo-client";
@@ -26,6 +26,8 @@ import { OfflineCallback } from "../client";
2626
import { SKIP_RETRY_KEY } from "./retry-link";
2727
import { OfflineEffectConfig } from "../store";
2828

29+
const logger = rootLogger.extend('offline-link');
30+
2931
const actions = {
3032
SAVE_SNAPSHOT: 'SAVE_SNAPSHOT',
3133
ENQUEUE: 'ENQUEUE_OFFLINE_MUTATION',
@@ -185,10 +187,6 @@ const enqueueMutation = <T>(operation: Operation, theStore: Store<OfflineCache>,
185187
return result;
186188
}
187189

188-
interface CanBeSilenced<TCache> extends ApolloCache<TCache> {
189-
silenceBroadcast?: boolean
190-
};
191-
192190
const effect = async <TCache extends NormalizedCacheObject>(
193191
store: Store<OfflineCache>,
194192
client: AWSAppSyncClient<TCache>,
@@ -197,7 +195,6 @@ const effect = async <TCache extends NormalizedCacheObject>(
197195
callback: OfflineCallback,
198196
): Promise<FetchResult<Record<string, any>, Record<string, any>>> => {
199197
const doIt = true;
200-
const { cache }: { cache: CanBeSilenced<TCache> } = client;
201198
const {
202199
optimisticResponse: origOptimistic,
203200
operation: { variables: origVars, query: mutation, context },
@@ -232,6 +229,7 @@ const effect = async <TCache extends NormalizedCacheObject>(
232229
};
233230
const operation = buildOperationForLink.call(client.queryManager, mutation, variables, extraContext);
234231

232+
logger('Executing link', operation);
235233
execute(client.link, operation).subscribe({
236234
next: data => {
237235
boundSaveServerId(store, optimisticResponse, data.data);
@@ -274,13 +272,16 @@ const effect = async <TCache extends NormalizedCacheObject>(
274272
} = effect as EnqueuedMutationEffect<any>;
275273

276274
if (typeof update !== 'function') {
275+
logger('No update function for mutation', { document, variables });
277276
return;
278277
}
279278

280279
const optimisticResponse = replaceUsingMap({ ...origOptimisticResponse }, idsMap);
281280
const result = { data: optimisticResponse };
282281

283282
if (fetchPolicy !== 'no-cache') {
283+
logger('Running update function for mutation', { document, variables });
284+
284285
dataStore.markMutationResult({
285286
mutationId: null,
286287
result,
@@ -334,7 +335,7 @@ const effect = async <TCache extends NormalizedCacheObject>(
334335
}
335336
},
336337
error: err => {
337-
// TODO: Undo cache updates?
338+
logger('Error when executing link', err);
338339

339340
reject(err);
340341
}
@@ -450,14 +451,10 @@ const discard = (callback: OfflineCallback, error, action, retries) => {
450451

451452
if (discardResult) {
452453
// Call global error callback or observer
453-
try {
454-
if (typeof callback === 'function') {
455-
tryFunctionOrLogError(() => {
456-
callback({ error }, null);
457-
});
458-
}
459-
} catch (error) {
460-
// TODO: warn
454+
if (typeof callback === 'function') {
455+
tryFunctionOrLogError(() => {
456+
callback({ error }, null);
457+
});
461458
}
462459
}
463460

@@ -468,15 +465,15 @@ const _discard = (error, action: OfflineAction, retries) => {
468465
const { graphQLErrors = [] }: { graphQLErrors: AWSAppsyncGraphQLError[] } = error;
469466

470467
if (graphQLErrors.length) {
471-
// console.error('Discarding action.', action, graphQLErrors);
468+
logger('Discarding action.', action, graphQLErrors);
472469

473470
return true;
474471
} else {
475472
const { networkError: { graphQLErrors = [] } = { graphQLErrors: [] } } = error;
476473
const appSyncClientError = graphQLErrors.find(err => err.errorType && err.errorType.startsWith('AWSAppSyncClient:'));
477474

478475
if (appSyncClientError) {
479-
// console.error('Discarding action.', action, appSyncClientError);
476+
logger('Discarding action.', action, appSyncClientError);
480477

481478
return true;
482479
}

packages/aws-appsync/src/link/subscription-handshake-link.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88
*/
99
import { ApolloLink, Observable, Operation, FetchResult } from "apollo-link";
1010

11+
import { rootLogger } from "../utils";
1112
import * as Paho from '../vendor/paho-mqtt';
1213
import { ApolloError } from "apollo-client";
1314
import { FieldNode } from "graphql";
1415
import { getMainDefinition } from "apollo-utilities";
1516

17+
const logger = rootLogger.extend('subscriptions');
18+
const mqttLogger = logger.extend('mqtt');
19+
1620
type SubscriptionExtension = {
1721
mqttConnections: MqttConnectionInfo[],
1822
newSubscriptions: NewSubscriptions,
@@ -161,7 +165,7 @@ export class SubscriptionHandshakeLink extends ApolloLink {
161165
const { client: clientId, url, topics } = connectionInfo;
162166
const client: any = new Paho.Client(url, clientId);
163167

164-
// client.trace = console.log.bind(null, clientId);
168+
client.trace = mqttLogger.bind(null, clientId);
165169
client.onConnectionLost = ({ errorCode, ...args }) => {
166170
if (errorCode !== 0) {
167171
topics.forEach(t => {
@@ -224,14 +228,16 @@ export class SubscriptionHandshakeLink extends ApolloLink {
224228
parsedMessage.data || {}
225229
);
226230

231+
logger('Message received', { data, topic, observers });
232+
227233
observers.forEach(observer => {
228234
try {
229235
observer.next({
230236
...parsedMessage,
231237
...{ data },
232238
})
233239
} catch (err) {
234-
// console.error(err);
240+
logger(err);
235241
}
236242
});
237243
}

packages/aws-appsync/src/store.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
77
* KIND, express or implied. See the License for the specific language governing permissions and limitations under the License.
88
*/
9+
import { rootLogger } from "./utils";
910
import { applyMiddleware, createStore, compose, combineReducers, Store, Reducer, AnyAction, ReducersMapObject } from 'redux';
1011
import { offline } from '@redux-offline/redux-offline';
1112
import defaultOfflineConfig from '@redux-offline/redux-offline/lib/defaults';
@@ -23,13 +24,16 @@ import { Observable } from 'apollo-link';
2324

2425
const { detectNetwork } = defaultOfflineConfig;
2526

27+
const logger = rootLogger.extend('store');
28+
2629
const newStore = <TCacheShape extends NormalizedCacheObject>(
2730
clientGetter: () => AWSAppSyncClient<TCacheShape> = () => null,
2831
persistCallback = () => null,
2932
dataIdFromObject: (obj) => string | null,
3033
storage: any,
3134
callback: OfflineCallback = () => { },
3235
): Store<any> => {
36+
logger('Creating store');
3337

3438
const store = createStore(
3539
combineReducers({
@@ -50,7 +54,11 @@ const newStore = <TCacheShape extends NormalizedCacheObject>(
5054
offline({
5155
...defaultOfflineConfig,
5256
retry: getEffectDelay,
53-
persistCallback,
57+
persistCallback: () => {
58+
logger('Storage ready');
59+
60+
persistCallback();
61+
},
5462
persistOptions: {
5563
...(storage && { storage }),
5664
whitelist: [
@@ -115,17 +123,24 @@ const effect = async (effect, action: OfflineAction, store, clientGetter, callba
115123
});
116124

117125
if (config && config.effect) {
126+
logger(`Executing effect for ${action.type}`);
127+
118128
return config.effect(store, clientGetter, effect, action, callback, observable);
119129
}
130+
131+
logger(`No effect found for ${action.type}`);
120132
};
121133

122134
const discard = (callback, error, action, retries) => {
123135
const { discard } = offlineEffectsConfigs[action.type];
124136

125137
if (discard) {
138+
logger(`Executing discard for ${action.type}`, discard);
139+
126140
return discard(callback, error, action, retries);
127141
}
128142

143+
logger(`No custom discard found for ${action.type}. Discarding effect.`);
129144
return true;
130145
};
131146

packages/aws-appsync/src/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ export const getOperationFieldName = (operation: DocumentNode): string => result
2121
);
2222

2323
export const hash = (src: any) => crypto.createHash('sha256').update(src || {}, 'utf8').digest('hex') as string;
24+
25+
export { default as rootLogger } from './logger';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import debug from 'debug';
2+
3+
export type Logger = Function & {
4+
extend(category: string): Logger;
5+
};
6+
7+
const debugLogger = debug('aws-appsync') as Logger;
8+
9+
const extend = function (category = '') {
10+
const newCategory = category ? [...this.namespace.split(':'), category].join(':') : this.namespace;
11+
12+
const result = debug(newCategory);
13+
result.extend = extend.bind(result);
14+
15+
return result;
16+
};
17+
debugLogger.extend = extend.bind(debugLogger);
18+
19+
export default debugLogger;

yarn.lock

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,12 +1774,6 @@ debug@^3.1.0:
17741774
dependencies:
17751775
ms "^2.1.1"
17761776

1777-
debug@^4.1.0:
1778-
version "4.1.0"
1779-
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87"
1780-
dependencies:
1781-
ms "^2.1.1"
1782-
17831777
debug@~2.2.0:
17841778
version "2.2.0"
17851779
resolved "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"

0 commit comments

Comments
 (0)