Skip to content

Commit bf85047

Browse files
authored
Log events from signals (#1186)
1 parent 8616fc8 commit bf85047

File tree

12 files changed

+177
-96
lines changed

12 files changed

+177
-96
lines changed

.changeset/shiny-boats-warn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-signals': patch
3+
---
4+
5+
Add signals logging for events

packages/signals/signals/src/core/debug-mode/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@ export const parseDebugModeQueryString = (): boolean | undefined => {
1717
/**
1818
* This turns on advanced logging for signals!
1919
*/
20-
export const parseSignalsLoggingAdvancedQueryString = ():
21-
| boolean
22-
| undefined => {
20+
export type LogLevelOptions = 'info' | 'debug' | 'off'
21+
export const parseSignalsLogLevel = (): LogLevelOptions | undefined => {
2322
const queryParams = new URLSearchParams(window.location.search)
2423

2524
const val =
26-
queryParams.get('segment_signals_logging_advanced') ||
27-
queryParams.get('seg_signals_logging_advanced')
28-
if (val === 'true' || val === 'false') {
29-
return val === 'true'
25+
queryParams.get('segment_signals_log_level') ||
26+
queryParams.get('seg_signals_log_level')
27+
if (val === 'info' || val === 'debug' || val === 'off') {
28+
return val
29+
} else if (typeof val === 'string') {
30+
console.error(
31+
`Invalid signals_log_level: "${val}". Valid options are: info, debug, off`
32+
)
3033
}
3134
return undefined
3235
}

packages/signals/signals/src/core/emitter/index.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,12 @@ export interface EmitSignal {
66
emit: (signal: Signal) => void
77
}
88

9-
interface SignalEmitterSettings {
10-
shouldLogSignals: () => boolean
11-
}
12-
139
export class SignalEmitter implements EmitSignal {
1410
private emitter = new Emitter<{ add: [Signal] }>()
1511
private listeners = new Set<(signal: Signal) => void>()
16-
private settings?: SignalEmitterSettings
17-
constructor(settings?: SignalEmitterSettings) {
18-
this.settings = settings
19-
}
12+
2013
emit(signal: Signal) {
21-
if (this.settings?.shouldLogSignals()) {
22-
logger.log('New signal:', signal.type, signal.data)
23-
}
14+
logger.info('New signal:', signal.type, signal.data)
2415
this.emitter.emit('add', signal)
2516
}
2617

packages/signals/signals/src/core/processor/processor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export class SignalEventProcessor {
1818
const name = methodName as MethodName
1919
const eventsCollection = analyticsMethodCalls[name]
2020
eventsCollection.forEach((args) => {
21-
logger.debug(`analytics.${name}(...) called with args`, args)
21+
logger.info('New method call:', `analytics.${name}()`, args)
22+
2223
// @ts-ignore
2324
this.analytics[name](...args)
2425
})

packages/signals/signals/src/core/signals/settings.ts

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { SignalsIngestSettingsConfig } from '../client'
55
import { SandboxSettingsConfig } from '../processor/sandbox'
66
import { NetworkSettingsConfig } from '../signal-generators/network-gen'
77
import { SignalsPluginSettingsConfig } from '../../types'
8-
import { DebugStorage } from '../../lib/storage/debug-storage'
8+
import { WebStorage } from '../../lib/storage/web-storage'
99

1010
export type SignalsSettingsConfig = Pick<
1111
SignalsPluginSettingsConfig,
@@ -114,22 +114,14 @@ export class SignalGlobalSettings {
114114
export class SignalsDebugSettings {
115115
private static redactionKey = 'segment_signals_debug_redaction_disabled'
116116
private static ingestionKey = 'segment_signals_debug_ingestion_enabled'
117-
private static logSignals = 'segment_signals_log_signals_enabled'
118-
storage: DebugStorage
117+
private storage = new WebStorage(window.sessionStorage)
119118

120119
constructor(disableRedaction?: boolean, enableIngestion?: boolean) {
121-
this.storage = new DebugStorage('sessionStorage')
122120
if (typeof disableRedaction === 'boolean') {
123-
this.storage.setDebugKey(
124-
SignalsDebugSettings.redactionKey,
125-
disableRedaction
126-
)
121+
this.storage.setItem(SignalsDebugSettings.redactionKey, disableRedaction)
127122
}
128123
if (typeof enableIngestion === 'boolean') {
129-
this.storage.setDebugKey(
130-
SignalsDebugSettings.ingestionKey,
131-
enableIngestion
132-
)
124+
this.storage.setItem(SignalsDebugSettings.ingestionKey, enableIngestion)
133125
}
134126

135127
const debugModeInQs = parseDebugModeQueryString()
@@ -140,20 +132,19 @@ export class SignalsDebugSettings {
140132
}
141133

142134
setAllDebugging = (boolean: boolean) => {
143-
this.storage.setDebugKey(SignalsDebugSettings.redactionKey, boolean)
144-
this.storage.setDebugKey(SignalsDebugSettings.ingestionKey, boolean)
145-
this.storage.setDebugKey(SignalsDebugSettings.logSignals, boolean)
135+
this.storage.setItem(SignalsDebugSettings.redactionKey, boolean)
136+
this.storage.setItem(SignalsDebugSettings.ingestionKey, boolean)
146137
}
147138

148139
getDisableSignalsRedaction = (): boolean => {
149-
return this.storage.getDebugKey(SignalsDebugSettings.redactionKey)
140+
return (
141+
this.storage.getItem<boolean>(SignalsDebugSettings.redactionKey) ?? false
142+
)
150143
}
151144

152145
getEnableSignalsIngestion = (): boolean => {
153-
return this.storage.getDebugKey(SignalsDebugSettings.ingestionKey)
154-
}
155-
156-
getEnableLogSignals = (): boolean => {
157-
return this.storage.getDebugKey(SignalsDebugSettings.logSignals)
146+
return (
147+
this.storage.getItem<boolean>(SignalsDebugSettings.ingestionKey) ?? false
148+
)
158149
}
159150
}

packages/signals/signals/src/core/signals/signals.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { SignalEventProcessor } from '../processor/processor'
1515
import { Sandbox, SandboxSettings } from '../processor/sandbox'
1616
import { SignalGlobalSettings, SignalsSettingsConfig } from './settings'
1717
import { logger } from '../../lib/logger'
18+
import { LogLevelOptions } from '../debug-mode'
1819

1920
interface ISignals {
2021
start(analytics: AnyAnalytics): Promise<void>
@@ -38,10 +39,7 @@ export class Signals implements ISignals {
3839
private globalSettings: SignalGlobalSettings
3940
constructor(settingsConfig: SignalsSettingsConfig = {}) {
4041
this.globalSettings = new SignalGlobalSettings(settingsConfig)
41-
this.signalEmitter = new SignalEmitter({
42-
shouldLogSignals: () =>
43-
this.globalSettings.signalsDebug.getEnableLogSignals(),
44-
})
42+
this.signalEmitter = new SignalEmitter()
4543
this.signalsClient = new SignalsIngestClient(
4644
this.globalSettings.ingestClient
4745
)
@@ -136,10 +134,11 @@ export class Signals implements ISignals {
136134
}
137135

138136
/**
139-
* Disable redaction, ingestion of signals, and other debug logging.
137+
* Disable redaction, ingestion of signals, and other logging.
140138
*/
141-
debug(boolean = true): void {
139+
debug(boolean = true, logLevel?: LogLevelOptions): void {
142140
this.globalSettings.signalsDebug.setAllDebugging(boolean)
141+
logger.enableLogging(logLevel ?? 'info')
143142
}
144143

145144
/**

packages/signals/signals/src/lib/logger/index.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,51 @@
1-
import { parseSignalsLoggingAdvancedQueryString } from '../../core/debug-mode'
2-
import { DebugStorage } from '../storage/debug-storage'
1+
import {
2+
LogLevelOptions,
3+
parseDebugModeQueryString,
4+
parseSignalsLogLevel,
5+
} from '../../core/debug-mode'
6+
import { WebStorage } from '../storage/web-storage'
37

48
class Logger {
5-
private static advancedLogging = 'segment_signals_logging_advanced'
9+
private logLevelKey = 'segment_signals_log_level'
10+
private storage = new WebStorage(window.sessionStorage)
11+
get logLevel(): LogLevelOptions {
12+
return this.storage.getItem(this.logLevelKey) ?? 'off'
13+
}
614

7-
storage = new DebugStorage('sessionStorage')
815
constructor() {
9-
const val = parseSignalsLoggingAdvancedQueryString()
10-
if (typeof val === 'boolean') {
11-
this.storage.setDebugKey(Logger.advancedLogging, val)
16+
// if log level is set in query string, use that, otherwise if debug mode is set, set log level to info
17+
const logLevel = parseSignalsLogLevel()
18+
if (logLevel !== undefined) {
19+
logLevel === 'off' ? this.disableLogging() : this.enableLogging(logLevel)
20+
} else {
21+
const debugMode = parseDebugModeQueryString()
22+
if (debugMode === true) {
23+
this.enableLogging('info')
24+
}
1225
}
1326
}
1427

15-
private debugLoggingEnabled = (): boolean => {
16-
return this.storage.getDebugKey(Logger.advancedLogging)
28+
enableLogging = (type: LogLevelOptions) => {
29+
this.storage.setItem(this.logLevelKey, type)
30+
}
31+
32+
disableLogging = () => {
33+
this.storage.setItem(this.logLevelKey, 'off')
1734
}
1835

19-
enableDebugLogging = (bool = true) => {
20-
this.storage.setDebugKey(Logger.advancedLogging, bool)
36+
private log = (level: 'info' | 'debug', ...args: any[]): void => {
37+
console.log(`[signals:${level}]`, ...args)
2138
}
2239

23-
log = (...args: any[]): void => {
24-
console.log('[signals log]', ...args)
40+
info = (...args: any[]): void => {
41+
if (this.logLevel === 'info' || this.logLevel === 'debug') {
42+
this.log('info', ...args)
43+
}
2544
}
2645

2746
debug = (...args: any[]): void => {
28-
if (this.debugLoggingEnabled()) {
29-
console.log('[signals debug]', ...args)
47+
if (this.logLevel === 'debug') {
48+
this.log('debug', ...args)
3049
}
3150
}
3251
}

packages/signals/signals/src/lib/__tests__/normalize-url.test.ts renamed to packages/signals/signals/src/lib/normalize-url/__tests__/normalize-url.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { setLocation } from '../../test-helpers/set-location'
2-
import { normalizeUrl } from '../normalize-url'
1+
import { setLocation } from '../../../test-helpers/set-location'
2+
import { normalizeUrl } from '..'
33

44
describe('normalizeUrl', () => {
55
beforeEach(() => {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { WebStorage } from '../web-storage'
2+
3+
describe('WebStorage', () => {
4+
let webStorage: WebStorage
5+
6+
beforeEach(() => {
7+
webStorage = new WebStorage(sessionStorage)
8+
})
9+
afterEach(() => {
10+
sessionStorage.clear()
11+
})
12+
describe('getItem, setItem', () => {
13+
it('should retrieve and parse a stored value from storage', () => {
14+
const key = 'testKey'
15+
const value = { foo: 'bar' }
16+
17+
webStorage.setItem(key, value)
18+
19+
const result = webStorage.getItem<typeof value>(key)
20+
21+
expect(result).toEqual(value)
22+
})
23+
24+
it('should return undefined if the key does not exist in storage', () => {
25+
const key = 'nonexistentKey'
26+
27+
const result = webStorage.getItem(key)
28+
expect(result).toBeUndefined()
29+
})
30+
31+
it('should handle JSON serializing errors gracefully when setting', () => {
32+
const key = 'testKey'
33+
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation()
34+
35+
webStorage.setItem(
36+
key,
37+
// @ts-ignore - intentational non-serializable value
38+
BigInt(1)
39+
)
40+
41+
expect(consoleWarnSpy).toHaveBeenCalledWith(
42+
'Storage set error',
43+
expect.any(Object),
44+
expect.any(Error)
45+
)
46+
})
47+
48+
it('should handle JSON parsing errors gracefully when retrieving', () => {
49+
const key = 'testKey'
50+
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation()
51+
52+
// if somehow invalid JSON is stored in the storage
53+
sessionStorage.setItem(key, 'invalid JSON')
54+
55+
const result = webStorage.getItem(key)
56+
57+
expect(result).toBeUndefined()
58+
expect(consoleWarnSpy).toHaveBeenCalledWith(
59+
'Storage retrieval error',
60+
expect.any(Object),
61+
expect.any(Error)
62+
)
63+
})
64+
})
65+
})

packages/signals/signals/src/lib/storage/debug-storage.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)