Skip to content

Commit cc2cf5f

Browse files
committed
♻️ refactor logging and implement in storage cache and getContacts
1 parent 09e422e commit cc2cf5f

File tree

3 files changed

+102
-76
lines changed

3 files changed

+102
-76
lines changed

src/cache/storage-cache.ts

Lines changed: 42 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import {
44
CacheItemStateType,
55
} from "../models/cache-item-state.model";
66
import { StorageAdapter } from "../models/storage-adapter.model";
7-
import { anonymizeKey } from "../util/anonymize-key";
7+
import { errorLogger, infoLogger } from "../util";
88

9-
const LOG_PREFIX = `[CACHE]`;
9+
const LOG_PREFIX = "CACHE";
1010
const CACHE_STATE_PREFIX = "cache-state:";
1111
const CACHE_STATE_SECONDS_TTL = 1800; // 30 minutes
1212

@@ -24,7 +24,8 @@ export class StorageCache implements ContactCache {
2424
Math.max(Number(CACHE_REFRESH_INTERVAL), 1) * 1000;
2525
}
2626

27-
this.log(
27+
infoLogger(
28+
LOG_PREFIX,
2829
`Initialized storage cache with maximum refresh interval of ${
2930
this.cacheRefreshIntervalMs / 1000
3031
}s.`
@@ -35,10 +36,8 @@ export class StorageCache implements ContactCache {
3536
key: string,
3637
getFreshValue?: (key: string) => Promise<Contact[]>
3738
): Promise<Contact[] | CacheItemState> {
38-
const anonKey = anonymizeKey(key);
39-
4039
try {
41-
this.log(`[${anonKey}] Trying to get contacts from cache`);
40+
infoLogger(LOG_PREFIX, "Trying to get contacts from cache", key);
4241

4342
const cacheItemState = await this.storage.get<CacheItemState>(
4443
this.getCacheItemKey(key)
@@ -47,14 +46,18 @@ export class StorageCache implements ContactCache {
4746
const contacts = await this.storage.get<Contact[]>(key);
4847

4948
if (cacheItemState?.state === CacheItemStateType.FETCHING) {
50-
this.log(
51-
`[${anonKey}] Not refreshing contacts, because cache state is FETCHING`
49+
infoLogger(
50+
LOG_PREFIX,
51+
"Not refreshing contacts, because cache state is FETCHING",
52+
key
5253
);
5354

5455
// if we have old contacts saved in cache we return them instead
5556
if (contacts && contacts?.length > 0) {
56-
this.log(
57-
`[${anonKey}] Returning previously cached contacts (${contacts.length}), because new contacts are still being fetched`
57+
infoLogger(
58+
LOG_PREFIX,
59+
`Returning previously cached contacts (${contacts.length}), because new contacts are still being fetched`,
60+
key
5861
);
5962
return contacts;
6063
}
@@ -63,7 +66,11 @@ export class StorageCache implements ContactCache {
6366
}
6467

6568
if (contacts) {
66-
this.log(`[${anonKey}] Found ${contacts.length} contacts in cache`);
69+
infoLogger(
70+
LOG_PREFIX,
71+
`Found ${contacts.length} contacts in cache`,
72+
key
73+
);
6774

6875
const now: number = new Date().getTime();
6976

@@ -74,40 +81,44 @@ export class StorageCache implements ContactCache {
7481
);
7582

7683
if (getFreshValue && isValueStale) {
77-
this.log(
78-
`[${anonKey}] cached value was stale, fetching fresh contacts`
84+
infoLogger(
85+
LOG_PREFIX,
86+
`Cached value was stale, fetching fresh contacts`,
87+
key
7988
);
89+
8090
// we don't return the fresh value here because we don't want to wait on the result.
8191
// We return the old value instead, the fresh value is returned the next time it is requested
8292
this.getRefreshed(key, getFreshValue).catch((error) => {
83-
this.logErr(`[${anonKey}] Unable to get fresh contacts`, error);
93+
errorLogger(LOG_PREFIX, `Unable to get fresh contacts`, error);
8494
});
8595
}
8696

8797
return contacts;
8898
}
8999
} catch (e) {
90-
this.logErr(`[${anonKey}] Unable to get contacts from cache`, e);
100+
errorLogger(LOG_PREFIX, `Unable to get contacts from cache`, key, e);
91101
}
92102

93103
if (!getFreshValue) {
94-
this.log(
95-
`[${anonKey}] No "getFreshValue" function provided - returning empty array`
104+
infoLogger(
105+
LOG_PREFIX,
106+
`No "getFreshValue" function provided - returning empty array`,
107+
key
96108
);
97109
return [];
98110
}
99111

100-
this.log(`[${anonKey}] Found no match in cache. Getting fresh value.`);
112+
infoLogger(LOG_PREFIX, `Found no match in cache. Getting fresh value`, key);
101113
return this.getRefreshed(key, getFreshValue);
102114
}
103115

104116
public async set(key: string, contacts: Contact[]): Promise<void> {
105-
const anonKey = anonymizeKey(key);
106-
this.log(`[${anonKey}] Saving ${contacts.length} contacts to cache`);
117+
infoLogger(LOG_PREFIX, `Saving ${contacts.length} contacts to cache`, key);
107118
try {
108119
await this.storage.set(key, contacts);
109120
} catch (e) {
110-
this.logErr(`[${anonKey}] Unable to set cache`, e);
121+
errorLogger(LOG_PREFIX, `Unable to set cache`, key, e);
111122
}
112123
}
113124

@@ -116,8 +127,7 @@ export class StorageCache implements ContactCache {
116127
state: CacheItemStateType,
117128
ttl?: number
118129
): Promise<void> {
119-
const anonKey = anonymizeKey(key);
120-
this.log(`[${anonKey}] Setting cache state to ${state}`);
130+
infoLogger(LOG_PREFIX, `Setting cache state to ${state}`, key);
121131
try {
122132
await this.storage.set(
123133
this.getCacheItemKey(key),
@@ -127,28 +137,25 @@ export class StorageCache implements ContactCache {
127137
},
128138
ttl
129139
);
130-
} catch (error) {
131-
this.logErr(`[${anonKey}] Unable to set cache state`, error);
140+
} catch (e) {
141+
errorLogger(LOG_PREFIX, `Unable to set cache state`, key, e);
132142
}
133143
}
134144

135145
public async delete(key: string): Promise<void> {
136-
const anonKey = anonymizeKey(key);
137-
this.log(`[${anonKey}] Removing contacts from cache`);
146+
infoLogger(LOG_PREFIX, `Removing contacts from cache`, key);
138147
try {
139148
await this.storage.delete(key);
140149
} catch (e) {
141-
this.logErr(`[${anonKey}] Unable to remove contacts from cache`, e);
150+
errorLogger(LOG_PREFIX, `Unable to remove contacts from cache`, key, e);
142151
}
143152
}
144153

145154
private async getRefreshed(
146155
key: string,
147156
getFreshValue: (key: string) => Promise<Contact[]>
148157
): Promise<Contact[]> {
149-
const anonKey = anonymizeKey(key);
150-
151-
this.log(`[${anonKey}] Setting cache state to FETCHING`);
158+
infoLogger(LOG_PREFIX, `Setting cache state to FETCHING`, key);
152159

153160
await this.setCacheState(
154161
key,
@@ -160,37 +167,19 @@ export class StorageCache implements ContactCache {
160167
const freshValue = await getFreshValue(key);
161168

162169
await this.set(key, freshValue);
163-
164-
this.log(`[${anonKey}] Setting cache state to CACHED`);
170+
infoLogger(LOG_PREFIX, `Setting cache state to CACHED`, key);
165171

166172
await this.setCacheState(key, CacheItemStateType.CACHED);
167173

168174
return freshValue;
169-
} catch (error) {
170-
this.log(`[${anonKey}] Error while refreshing value`, error);
175+
} catch (e) {
176+
errorLogger(LOG_PREFIX, `Error while refreshing value`, key, e);
171177
await this.storage.delete(this.getCacheItemKey(key));
172-
throw error;
178+
throw e;
173179
}
174180
}
175181

176182
private getCacheItemKey(key: string) {
177183
return `${CACHE_STATE_PREFIX}${key}`;
178184
}
179-
180-
private log(...args: any) {
181-
console.log(this.constructLogMessage(args));
182-
}
183-
184-
private logErr(...args: any) {
185-
console.error(this.constructLogMessage(args));
186-
}
187-
188-
private constructLogMessage(...args: any) {
189-
return `${LOG_PREFIX} ${args
190-
.flat()
191-
.map((item: unknown) =>
192-
typeof item !== "string" ? JSON.stringify(item) : item
193-
)
194-
.join(" ")}`;
195-
}
196185
}

src/models/controller.model.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,19 @@ export class Controller {
5959
): Promise<void> {
6060
const { providerConfig } = req;
6161

62+
if (!providerConfig) {
63+
throw new ServerError(400, "Missing parameters");
64+
}
65+
6266
try {
63-
if (!providerConfig) {
64-
throw new ServerError(400, "Missing parameters");
65-
}
67+
infoLogger("getContacts", "START", providerConfig.apiKey);
6668

6769
const fetchContacts = async (): Promise<Contact[]> => {
6870
if (!this.adapter.getContacts) {
6971
throw new ServerError(501, "Fetching contacts is not implemented");
7072
}
7173

72-
infoLogger(`Fetching contacts…`, providerConfig);
74+
infoLogger("getContacts", `Fetching contacts…`, providerConfig.apiKey);
7375

7476
const fetchedContacts: Contact[] = await this.adapter.getContacts(
7577
providerConfig
@@ -103,7 +105,11 @@ export class Controller {
103105

104106
const contactsCount = responseContacts.length;
105107

106-
infoLogger(`Found ${contactsCount} cached contacts.`, providerConfig);
108+
infoLogger(
109+
"getContacts",
110+
`Found ${contactsCount} cached contacts`,
111+
providerConfig.apiKey
112+
);
107113

108114
if (
109115
!Array.isArray(raceResult) &&
@@ -118,8 +124,9 @@ export class Controller {
118124
res.header("X-Provider-Key", apiKey);
119125
}
120126

127+
infoLogger("getContacts", "END", providerConfig.apiKey);
121128
res.status(200).send(responseContacts);
122-
} catch (error) {
129+
} catch (error: any) {
123130
// prevent logging of refresh errors
124131
if (
125132
error instanceof ServerError &&
@@ -130,9 +137,10 @@ export class Controller {
130137
}
131138

132139
errorLogger(
140+
"getContacts",
133141
"Could not get contacts:",
134-
providerConfig,
135-
error || "Unknown"
142+
providerConfig.apiKey,
143+
error
136144
);
137145
next(error);
138146
}

src/util/logger.util.ts

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,78 @@ import { anonymizeKey } from "./anonymize-key";
22
import { Config } from "../models";
33

44
export const infoLogger = (
5+
source: string,
56
message: string,
6-
config?: Config,
7+
apiKey?: string,
78
...args: unknown[]
89
): void => {
910
// eslint-disable-next-line no-console
10-
if (config) {
11+
if (apiKey) {
1112
console.log(
12-
`${`[${anonymizeKey(config.apiKey)}]`}: ${message}`,
13-
args && args.length ? args : ""
13+
constructLogMessage(
14+
`[${anonymizeKey(apiKey)}]`,
15+
`[${source.toUpperCase()}]`,
16+
message,
17+
args
18+
)
1419
);
1520
} else {
16-
console.log(message, args && args.length ? args : "");
21+
console.log(
22+
constructLogMessage(`[${source.toUpperCase()}]`, message, args)
23+
);
1724
}
1825
};
1926

2027
export const errorLogger = (
28+
source: string,
2129
message: string,
22-
config?: Config,
30+
apiKey?: string,
2331
...args: unknown[]
2432
): void => {
2533
// eslint-disable-next-line no-console
26-
if (config?.apiKey) {
34+
if (apiKey) {
2735
console.error(
28-
`[${anonymizeKey(config.apiKey)}] ${message}`,
29-
args && args.length ? args : ""
36+
constructLogMessage(
37+
`[${anonymizeKey(apiKey)}]`,
38+
`[${source.toUpperCase()}]`,
39+
message,
40+
args
41+
)
3042
);
3143
} else {
32-
console.error(message, args && args.length ? args : "");
44+
console.error(
45+
constructLogMessage(`[${source.toUpperCase()}]`, message, args)
46+
);
3347
}
3448
};
3549

3650
export const warnLogger = (
51+
source: string,
3752
message: string,
38-
config?: Config,
53+
apiKey?: string,
3954
...args: unknown[]
4055
): void => {
4156
// eslint-disable-next-line no-console
42-
if (config?.apiKey) {
57+
if (apiKey) {
4358
console.warn(
44-
`[${anonymizeKey(config.apiKey)}] ${message}`,
45-
args && args.length ? args : ""
59+
constructLogMessage(
60+
`[${anonymizeKey(apiKey)}]`,
61+
`[${source.toUpperCase()}]`,
62+
message,
63+
args
64+
)
4665
);
4766
} else {
48-
console.warn(message, args && args.length ? args : "");
67+
console.warn(
68+
constructLogMessage(`[${source.toUpperCase()}]`, message, args)
69+
);
4970
}
5071
};
72+
73+
const constructLogMessage = (...args: unknown[]): string =>
74+
`${args
75+
.flat()
76+
.map((item: unknown) =>
77+
typeof item !== "string" ? JSON.stringify(item) : item
78+
)
79+
.join(" ")}`;

0 commit comments

Comments
 (0)