@kubesense/kubesense-browser-logs 0.0.0-stage → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +90 -2
- package/bundle/kubesense-logs.js +1 -0
- package/cjs/boot/logsPublicApi.d.ts +231 -0
- package/cjs/boot/logsPublicApi.js +75 -0
- package/cjs/boot/logsPublicApi.js.map +1 -0
- package/cjs/boot/preStartLogs.d.ts +8 -0
- package/cjs/boot/preStartLogs.js +105 -0
- package/cjs/boot/preStartLogs.js.map +1 -0
- package/cjs/boot/startLogs.d.ts +35 -0
- package/cjs/boot/startLogs.js +54 -0
- package/cjs/boot/startLogs.js.map +1 -0
- package/cjs/domain/assembly.d.ts +5 -0
- package/cjs/domain/assembly.js +35 -0
- package/cjs/domain/assembly.js.map +1 -0
- package/cjs/domain/configuration.d.ts +306 -0
- package/cjs/domain/configuration.js +86 -0
- package/cjs/domain/configuration.js.map +1 -0
- package/cjs/domain/console/consoleCollection.d.ts +20 -0
- package/cjs/domain/console/consoleCollection.js +37 -0
- package/cjs/domain/console/consoleCollection.js.map +1 -0
- package/cjs/domain/contexts/commonContext.d.ts +2 -0
- package/cjs/domain/contexts/commonContext.js +13 -0
- package/cjs/domain/contexts/commonContext.js.map +1 -0
- package/cjs/domain/contexts/internalContext.d.ts +7 -0
- package/cjs/domain/contexts/internalContext.js +11 -0
- package/cjs/domain/contexts/internalContext.js.map +1 -0
- package/cjs/domain/contexts/rumInternalContext.d.ts +2 -0
- package/cjs/domain/contexts/rumInternalContext.js +32 -0
- package/cjs/domain/contexts/rumInternalContext.js.map +1 -0
- package/cjs/domain/contexts/sessionContext.d.ts +4 -0
- package/cjs/domain/contexts/sessionContext.js +20 -0
- package/cjs/domain/contexts/sessionContext.js.map +1 -0
- package/cjs/domain/contexts/trackingConsentContext.d.ts +3 -0
- package/cjs/domain/contexts/trackingConsentContext.js +14 -0
- package/cjs/domain/contexts/trackingConsentContext.js.map +1 -0
- package/cjs/domain/createErrorFieldFromRawError.d.ts +10 -0
- package/cjs/domain/createErrorFieldFromRawError.js +15 -0
- package/cjs/domain/createErrorFieldFromRawError.js.map +1 -0
- package/cjs/domain/hooks.d.ts +28 -0
- package/cjs/domain/hooks.js +13 -0
- package/cjs/domain/hooks.js.map +1 -0
- package/cjs/domain/lifeCycle.d.ts +24 -0
- package/cjs/domain/lifeCycle.js +6 -0
- package/cjs/domain/lifeCycle.js.map +1 -0
- package/cjs/domain/logger/isAuthorized.d.ts +17 -0
- package/cjs/domain/logger/isAuthorized.js +34 -0
- package/cjs/domain/logger/isAuthorized.js.map +1 -0
- package/cjs/domain/logger/loggerCollection.d.ts +7 -0
- package/cjs/domain/logger/loggerCollection.js +47 -0
- package/cjs/domain/logger/loggerCollection.js.map +1 -0
- package/cjs/domain/logger.d.ts +48 -0
- package/cjs/domain/logger.js +112 -0
- package/cjs/domain/logger.js.map +1 -0
- package/cjs/domain/networkError/networkErrorCollection.d.ts +9 -0
- package/cjs/domain/networkError/networkErrorCollection.js +57 -0
- package/cjs/domain/networkError/networkErrorCollection.js.map +1 -0
- package/cjs/domain/plugins.d.ts +49 -0
- package/cjs/domain/plugins.js +12 -0
- package/cjs/domain/plugins.js.map +1 -0
- package/cjs/domain/remoteSdkConfiguration.d.ts +26 -0
- package/cjs/domain/remoteSdkConfiguration.js +67 -0
- package/cjs/domain/remoteSdkConfiguration.js.map +1 -0
- package/cjs/domain/report/reportCollection.d.ts +13 -0
- package/cjs/domain/report/reportCollection.js +30 -0
- package/cjs/domain/report/reportCollection.js.map +1 -0
- package/cjs/domain/reportError.d.ts +2 -0
- package/cjs/domain/reportError.js +20 -0
- package/cjs/domain/reportError.js.map +1 -0
- package/cjs/domain/runtimeError/runtimeErrorCollection.d.ts +14 -0
- package/cjs/domain/runtimeError/runtimeErrorCollection.js +29 -0
- package/cjs/domain/runtimeError/runtimeErrorCollection.js.map +1 -0
- package/cjs/domainContext.types.d.ts +11 -0
- package/cjs/entries/main.d.ts +33 -0
- package/cjs/entries/main.js +31 -0
- package/cjs/entries/main.js.map +1 -0
- package/cjs/logsEvent.types.d.ts +192 -0
- package/cjs/rawLogsEvent.types.d.ts +59 -0
- package/cjs/transport/startLogsBatch.d.ts +4 -0
- package/cjs/transport/startLogsBatch.js +22 -0
- package/cjs/transport/startLogsBatch.js.map +1 -0
- package/cjs/transport/startLogsBridge.d.ts +2 -0
- package/cjs/transport/startLogsBridge.js +13 -0
- package/cjs/transport/startLogsBridge.js.map +1 -0
- package/esm/boot/logsPublicApi.mjs +75 -0
- package/esm/boot/logsPublicApi.mjs.map +1 -0
- package/esm/boot/preStartLogs.mjs +105 -0
- package/esm/boot/preStartLogs.mjs.map +1 -0
- package/esm/boot/startLogs.mjs +54 -0
- package/esm/boot/startLogs.mjs.map +1 -0
- package/esm/domain/assembly.mjs +35 -0
- package/esm/domain/assembly.mjs.map +1 -0
- package/esm/domain/configuration.mjs +84 -0
- package/esm/domain/configuration.mjs.map +1 -0
- package/esm/domain/console/consoleCollection.mjs +36 -0
- package/esm/domain/console/consoleCollection.mjs.map +1 -0
- package/esm/domain/contexts/commonContext.mjs +13 -0
- package/esm/domain/contexts/commonContext.mjs.map +1 -0
- package/esm/domain/contexts/internalContext.mjs +11 -0
- package/esm/domain/contexts/internalContext.mjs.map +1 -0
- package/esm/domain/contexts/rumInternalContext.mjs +32 -0
- package/esm/domain/contexts/rumInternalContext.mjs.map +1 -0
- package/esm/domain/contexts/sessionContext.mjs +20 -0
- package/esm/domain/contexts/sessionContext.mjs.map +1 -0
- package/esm/domain/contexts/trackingConsentContext.mjs +14 -0
- package/esm/domain/contexts/trackingConsentContext.mjs.map +1 -0
- package/esm/domain/createErrorFieldFromRawError.mjs +15 -0
- package/esm/domain/createErrorFieldFromRawError.mjs.map +1 -0
- package/esm/domain/hooks.mjs +13 -0
- package/esm/domain/hooks.mjs.map +1 -0
- package/esm/domain/lifeCycle.mjs +7 -0
- package/esm/domain/lifeCycle.mjs.map +1 -0
- package/esm/domain/logger/isAuthorized.mjs +32 -0
- package/esm/domain/logger/isAuthorized.mjs.map +1 -0
- package/esm/domain/logger/loggerCollection.mjs +47 -0
- package/esm/domain/logger/loggerCollection.mjs.map +1 -0
- package/esm/domain/logger.mjs +110 -0
- package/esm/domain/logger.mjs.map +1 -0
- package/esm/domain/networkError/networkErrorCollection.mjs +56 -0
- package/esm/domain/networkError/networkErrorCollection.mjs.map +1 -0
- package/esm/domain/plugins.mjs +12 -0
- package/esm/domain/plugins.mjs.map +1 -0
- package/esm/domain/remoteSdkConfiguration.mjs +65 -0
- package/esm/domain/remoteSdkConfiguration.mjs.map +1 -0
- package/esm/domain/report/reportCollection.mjs +30 -0
- package/esm/domain/report/reportCollection.mjs.map +1 -0
- package/esm/domain/reportError.mjs +20 -0
- package/esm/domain/reportError.mjs.map +1 -0
- package/esm/domain/runtimeError/runtimeErrorCollection.mjs +29 -0
- package/esm/domain/runtimeError/runtimeErrorCollection.mjs.map +1 -0
- package/esm/entries/main.mjs +27 -0
- package/esm/entries/main.mjs.map +1 -0
- package/esm/transport/startLogsBatch.mjs +22 -0
- package/esm/transport/startLogsBatch.mjs.map +1 -0
- package/esm/transport/startLogsBridge.mjs +13 -0
- package/esm/transport/startLogsBridge.mjs.map +1 -0
- package/package.json +53 -3
- package/src/boot/logsPublicApi.ts +427 -0
- package/src/boot/preStartLogs.ts +192 -0
- package/src/boot/startLogs.ts +83 -0
- package/src/domain/assembly.ts +73 -0
- package/src/domain/configuration.ts +176 -0
- package/src/domain/console/consoleCollection.ts +58 -0
- package/src/domain/contexts/commonContext.ts +15 -0
- package/src/domain/contexts/internalContext.ts +19 -0
- package/src/domain/contexts/rumInternalContext.ts +60 -0
- package/src/domain/contexts/sessionContext.ts +34 -0
- package/src/domain/contexts/trackingConsentContext.ts +18 -0
- package/src/domain/createErrorFieldFromRawError.ts +22 -0
- package/src/domain/hooks.ts +40 -0
- package/src/domain/lifeCycle.ts +25 -0
- package/src/domain/logger/isAuthorized.ts +33 -0
- package/src/domain/logger/loggerCollection.ts +69 -0
- package/src/domain/logger.ts +202 -0
- package/src/domain/networkError/networkErrorCollection.ts +104 -0
- package/src/domain/plugins.ts +72 -0
- package/src/domain/remoteSdkConfiguration.ts +105 -0
- package/src/domain/report/reportCollection.ts +47 -0
- package/src/domain/reportError.ts +20 -0
- package/src/domain/runtimeError/runtimeErrorCollection.ts +51 -0
- package/src/domainContext.types.ts +21 -0
- package/src/entries/main.ts +65 -0
- package/src/logsEvent.types.ts +198 -0
- package/src/rawLogsEvent.types.ts +74 -0
- package/src/transport/startLogsBatch.ts +29 -0
- package/src/transport/startLogsBridge.ts +13 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { timeStampNow } from '@kubesense/kubesense-js-core/time'
|
|
2
|
+
import type { TimeStamp } from '@kubesense/kubesense-js-core/time'
|
|
3
|
+
import type { Context } from '@kubesense/kubesense-browser-core'
|
|
4
|
+
import { ErrorSource } from '@kubesense/kubesense-browser-core'
|
|
5
|
+
import { originalConsoleMethods, globalConsole, ConsoleApiName, combine } from '@kubesense/kubesense-js-core/util'
|
|
6
|
+
import type { CommonContext, RawLogsEvent } from '../../rawLogsEvent.types'
|
|
7
|
+
import type { LifeCycle, RawLogsEventCollectedData } from '../lifeCycle'
|
|
8
|
+
import { LifeCycleEventType } from '../lifeCycle'
|
|
9
|
+
import type { Logger, LogsMessage } from '../logger'
|
|
10
|
+
import { HandlerType } from '../logger'
|
|
11
|
+
import { isAuthorized, StatusType } from './isAuthorized'
|
|
12
|
+
|
|
13
|
+
export function startLoggerCollection(lifeCycle: LifeCycle) {
|
|
14
|
+
function handleLog(
|
|
15
|
+
logsMessage: LogsMessage,
|
|
16
|
+
logger: Logger,
|
|
17
|
+
handlingStack?: string,
|
|
18
|
+
savedCommonContext?: CommonContext,
|
|
19
|
+
savedDate?: TimeStamp
|
|
20
|
+
) {
|
|
21
|
+
const messageContext = combine(logger.getContext(), logsMessage.context)
|
|
22
|
+
|
|
23
|
+
if (isAuthorized(logsMessage.status, HandlerType.console, logger)) {
|
|
24
|
+
displayInConsole(logsMessage, messageContext)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isAuthorized(logsMessage.status, HandlerType.http, logger)) {
|
|
28
|
+
const rawLogEventData: RawLogsEventCollectedData<RawLogsEvent> = {
|
|
29
|
+
rawLogsEvent: combine(
|
|
30
|
+
{
|
|
31
|
+
date: savedDate || timeStampNow(),
|
|
32
|
+
message: logsMessage.message,
|
|
33
|
+
status: logsMessage.status,
|
|
34
|
+
origin: ErrorSource.LOGGER,
|
|
35
|
+
_kubesense: { debug_ids: logsMessage.debugIds },
|
|
36
|
+
},
|
|
37
|
+
messageContext
|
|
38
|
+
),
|
|
39
|
+
savedCommonContext,
|
|
40
|
+
ktags: logger.getTags(),
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (handlingStack) {
|
|
44
|
+
rawLogEventData.domainContext = { handlingStack }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
lifeCycle.notify(LifeCycleEventType.RAW_LOG_COLLECTED, rawLogEventData)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
handleLog,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const loggerToConsoleApiName: { [key in StatusType]: ConsoleApiName } = {
|
|
56
|
+
[StatusType.ok]: ConsoleApiName.debug,
|
|
57
|
+
[StatusType.debug]: ConsoleApiName.debug,
|
|
58
|
+
[StatusType.info]: ConsoleApiName.info,
|
|
59
|
+
[StatusType.notice]: ConsoleApiName.info,
|
|
60
|
+
[StatusType.warn]: ConsoleApiName.warn,
|
|
61
|
+
[StatusType.error]: ConsoleApiName.error,
|
|
62
|
+
[StatusType.critical]: ConsoleApiName.error,
|
|
63
|
+
[StatusType.alert]: ConsoleApiName.error,
|
|
64
|
+
[StatusType.emerg]: ConsoleApiName.error,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function displayInConsole({ status, message }: LogsMessage, messageContext: Context | undefined) {
|
|
68
|
+
originalConsoleMethods[loggerToConsoleApiName[status]].call(globalConsole, message, messageContext)
|
|
69
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { Context, ContextManager, DebugIdEntry } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import { clocksNow } from '@kubesense/kubesense-js-core/time'
|
|
3
|
+
import { combine } from '@kubesense/kubesense-js-core/util'
|
|
4
|
+
import {
|
|
5
|
+
computeRawError,
|
|
6
|
+
ErrorHandling,
|
|
7
|
+
createContextManager,
|
|
8
|
+
ErrorSource,
|
|
9
|
+
sanitize,
|
|
10
|
+
NonErrorPrefix,
|
|
11
|
+
createHandlingStack,
|
|
12
|
+
buildTag,
|
|
13
|
+
sanitizeTag,
|
|
14
|
+
} from '@kubesense/kubesense-browser-core'
|
|
15
|
+
import { callMonitored } from '@kubesense/kubesense-js-core/monitor'
|
|
16
|
+
|
|
17
|
+
import { isAuthorized, StatusType } from './logger/isAuthorized'
|
|
18
|
+
import { createErrorFieldFromRawError } from './createErrorFieldFromRawError'
|
|
19
|
+
|
|
20
|
+
export interface LogsMessage {
|
|
21
|
+
message: string
|
|
22
|
+
status: StatusType
|
|
23
|
+
context?: Context
|
|
24
|
+
debugIds?: DebugIdEntry[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const HandlerType = {
|
|
28
|
+
console: 'console',
|
|
29
|
+
http: 'http',
|
|
30
|
+
silent: 'silent',
|
|
31
|
+
} as const
|
|
32
|
+
|
|
33
|
+
export type HandlerType = (typeof HandlerType)[keyof typeof HandlerType]
|
|
34
|
+
export const STATUSES = Object.keys(StatusType) as StatusType[]
|
|
35
|
+
|
|
36
|
+
// note: it is safe to merge declarations as long as the methods are actually defined on the prototype
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging, no-restricted-syntax
|
|
38
|
+
export class Logger {
|
|
39
|
+
private contextManager: ContextManager
|
|
40
|
+
|
|
41
|
+
// Tags are formatted as either `key:value` or `key_only`
|
|
42
|
+
private tags: string[]
|
|
43
|
+
|
|
44
|
+
constructor(
|
|
45
|
+
private handleLogStrategy: (logsMessage: LogsMessage, logger: Logger, handlingStack?: string) => void,
|
|
46
|
+
name?: string,
|
|
47
|
+
private handlerType: HandlerType | HandlerType[] = HandlerType.http,
|
|
48
|
+
private level: StatusType = StatusType.debug,
|
|
49
|
+
loggerContext: object = {}
|
|
50
|
+
) {
|
|
51
|
+
this.contextManager = createContextManager('logger')
|
|
52
|
+
this.tags = []
|
|
53
|
+
this.contextManager.setContext(loggerContext)
|
|
54
|
+
if (name) {
|
|
55
|
+
this.contextManager.setContextProperty('logger', { name })
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
logImplementation(
|
|
60
|
+
message: string,
|
|
61
|
+
messageContext?: object,
|
|
62
|
+
status: StatusType = StatusType.info,
|
|
63
|
+
error?: Error,
|
|
64
|
+
handlingStack?: string
|
|
65
|
+
) {
|
|
66
|
+
callMonitored(() => {
|
|
67
|
+
const sanitizedMessageContext = sanitize(messageContext) as Context
|
|
68
|
+
let context: Context
|
|
69
|
+
let debugIds: DebugIdEntry[] | undefined
|
|
70
|
+
|
|
71
|
+
if (error !== undefined && error !== null) {
|
|
72
|
+
const rawError = computeRawError({
|
|
73
|
+
originalError: error,
|
|
74
|
+
nonErrorPrefix: NonErrorPrefix.PROVIDED,
|
|
75
|
+
source: ErrorSource.LOGGER,
|
|
76
|
+
handling: ErrorHandling.HANDLED,
|
|
77
|
+
startClocks: clocksNow(),
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
debugIds = rawError.debugIds
|
|
81
|
+
context = combine(
|
|
82
|
+
{
|
|
83
|
+
error: createErrorFieldFromRawError(rawError, { includeMessage: true }),
|
|
84
|
+
},
|
|
85
|
+
rawError.context,
|
|
86
|
+
sanitizedMessageContext
|
|
87
|
+
)
|
|
88
|
+
} else {
|
|
89
|
+
context = sanitizedMessageContext
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.handleLogStrategy(
|
|
93
|
+
{
|
|
94
|
+
message: sanitize(message)!,
|
|
95
|
+
context,
|
|
96
|
+
status,
|
|
97
|
+
...(debugIds ? { debugIds } : {}),
|
|
98
|
+
},
|
|
99
|
+
this,
|
|
100
|
+
handlingStack
|
|
101
|
+
)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
log(message: string, messageContext?: object, status: StatusType = StatusType.info, error?: Error) {
|
|
106
|
+
let handlingStack: string | undefined
|
|
107
|
+
|
|
108
|
+
if (isAuthorized(status, HandlerType.http, this)) {
|
|
109
|
+
handlingStack = createHandlingStack('log')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
this.logImplementation(message, messageContext, status, error, handlingStack)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
setContext(context: object) {
|
|
116
|
+
this.contextManager.setContext(context)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getContext() {
|
|
120
|
+
return this.contextManager.getContext()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
setContextProperty(key: string, value: any) {
|
|
124
|
+
this.contextManager.setContextProperty(key, value)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
removeContextProperty(key: string) {
|
|
128
|
+
this.contextManager.removeContextProperty(key)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
clearContext() {
|
|
132
|
+
this.contextManager.clearContext()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
addTag(key: string, value?: string) {
|
|
136
|
+
this.tags.push(buildTag(key, value))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
removeTagsWithKey(key: string) {
|
|
140
|
+
const sanitizedKey = sanitizeTag(key)
|
|
141
|
+
|
|
142
|
+
this.tags = this.tags.filter((tag) => tag !== sanitizedKey && !tag.startsWith(`${sanitizedKey}:`))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getTags() {
|
|
146
|
+
return this.tags.slice()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
setHandler(handler: HandlerType | HandlerType[]) {
|
|
150
|
+
this.handlerType = handler
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
getHandler() {
|
|
154
|
+
return this.handlerType
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setLevel(level: StatusType) {
|
|
158
|
+
this.level = level
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getLevel() {
|
|
162
|
+
return this.level
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* eslint-disable local-rules/disallow-side-effects */
|
|
167
|
+
Logger.prototype.ok = createLoggerMethod(StatusType.ok)
|
|
168
|
+
Logger.prototype.debug = createLoggerMethod(StatusType.debug)
|
|
169
|
+
Logger.prototype.info = createLoggerMethod(StatusType.info)
|
|
170
|
+
Logger.prototype.notice = createLoggerMethod(StatusType.notice)
|
|
171
|
+
Logger.prototype.warn = createLoggerMethod(StatusType.warn)
|
|
172
|
+
Logger.prototype.error = createLoggerMethod(StatusType.error)
|
|
173
|
+
Logger.prototype.critical = createLoggerMethod(StatusType.critical)
|
|
174
|
+
Logger.prototype.alert = createLoggerMethod(StatusType.alert)
|
|
175
|
+
Logger.prototype.emerg = createLoggerMethod(StatusType.emerg)
|
|
176
|
+
/* eslint-enable local-rules/disallow-side-effects */
|
|
177
|
+
|
|
178
|
+
// note: it is safe to merge declarations as long as the methods are actually defined on the prototype
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
180
|
+
export interface Logger {
|
|
181
|
+
ok(message: string, messageContext?: object, error?: Error): void
|
|
182
|
+
debug(message: string, messageContext?: object, error?: Error): void
|
|
183
|
+
info(message: string, messageContext?: object, error?: Error): void
|
|
184
|
+
notice(message: string, messageContext?: object, error?: Error): void
|
|
185
|
+
warn(message: string, messageContext?: object, error?: Error): void
|
|
186
|
+
error(message: string, messageContext?: object, error?: Error): void
|
|
187
|
+
critical(message: string, messageContext?: object, error?: Error): void
|
|
188
|
+
alert(message: string, messageContext?: object, error?: Error): void
|
|
189
|
+
emerg(message: string, messageContext?: object, error?: Error): void
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function createLoggerMethod(status: StatusType) {
|
|
193
|
+
return function (this: Logger, message: string, messageContext?: object, error?: Error) {
|
|
194
|
+
let handlingStack: string | undefined
|
|
195
|
+
|
|
196
|
+
if (isAuthorized(status, HandlerType.http, this)) {
|
|
197
|
+
handlingStack = createHandlingStack('log')
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this.logImplementation(message, messageContext, status, error, handlingStack)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FetchResolveContext,
|
|
3
|
+
XhrCompleteContext,
|
|
4
|
+
Observable,
|
|
5
|
+
BufferedData,
|
|
6
|
+
} from '@kubesense/kubesense-browser-core'
|
|
7
|
+
import {
|
|
8
|
+
BufferedDataType,
|
|
9
|
+
ErrorSource,
|
|
10
|
+
RequestType,
|
|
11
|
+
initFetchObservable,
|
|
12
|
+
computeStackTrace,
|
|
13
|
+
toStackTraceString,
|
|
14
|
+
noop,
|
|
15
|
+
isServerError,
|
|
16
|
+
ResponseBodyAction,
|
|
17
|
+
safeTruncate,
|
|
18
|
+
ONE_KIBI_BYTE,
|
|
19
|
+
buildDebugIdByUrl,
|
|
20
|
+
getStackTraceUrls,
|
|
21
|
+
} from '@kubesense/kubesense-browser-core'
|
|
22
|
+
import { isIntakeUrl } from '@kubesense/kubesense-js-core/transport'
|
|
23
|
+
import type { LogsConfiguration } from '../configuration'
|
|
24
|
+
|
|
25
|
+
/** arbitrary value, byte precision not needed */
|
|
26
|
+
export const DEFAULT_REQUEST_ERROR_RESPONSE_LENGTH_LIMIT = 32 * ONE_KIBI_BYTE
|
|
27
|
+
import type { LifeCycle } from '../lifeCycle'
|
|
28
|
+
import type { LogsEventDomainContext } from '../../domainContext.types'
|
|
29
|
+
import { LifeCycleEventType } from '../lifeCycle'
|
|
30
|
+
import { StatusType } from '../logger/isAuthorized'
|
|
31
|
+
|
|
32
|
+
export function startNetworkErrorCollection(
|
|
33
|
+
configuration: LogsConfiguration,
|
|
34
|
+
lifeCycle: LifeCycle,
|
|
35
|
+
bufferedDataObservable: Observable<BufferedData>
|
|
36
|
+
) {
|
|
37
|
+
if (!configuration.forwardErrorsToLogs) {
|
|
38
|
+
return { stop: noop }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Register responseBodyAction getter (no subscription needed)
|
|
42
|
+
initFetchObservable({
|
|
43
|
+
responseBodyAction: (context) => (isNetworkError(context) ? ResponseBodyAction.COLLECT : ResponseBodyAction.IGNORE),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const subscription = bufferedDataObservable.subscribe(({ data, type }) => {
|
|
47
|
+
if (type === BufferedDataType.FETCH && data.state === 'resolve') {
|
|
48
|
+
handleResponse(RequestType.FETCH, data)
|
|
49
|
+
} else if (type === BufferedDataType.XHR && data.state === 'complete') {
|
|
50
|
+
handleResponse(RequestType.XHR, data)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
function isNetworkError(request: XhrCompleteContext | FetchResolveContext) {
|
|
55
|
+
return !isIntakeUrl(request.url) && !request.isAborted && (isRejected(request) || isServerError(request.status))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function handleResponse(type: RequestType, request: XhrCompleteContext | FetchResolveContext) {
|
|
59
|
+
if (!isNetworkError(request)) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
const stackTrace = 'error' in request && request.error ? computeStackTrace(request.error) : undefined
|
|
63
|
+
const stack = stackTrace ? toStackTraceString(stackTrace) : request.responseBody || 'Failed to load'
|
|
64
|
+
const debugIds = stackTrace ? buildDebugIdByUrl(getStackTraceUrls(stackTrace)) : undefined
|
|
65
|
+
|
|
66
|
+
const domainContext: LogsEventDomainContext<typeof ErrorSource.NETWORK> = {
|
|
67
|
+
handlingStack: request.handlingStack,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
lifeCycle.notify(LifeCycleEventType.RAW_LOG_COLLECTED, {
|
|
71
|
+
rawLogsEvent: {
|
|
72
|
+
message: `${format(type)} error ${request.method} ${request.url}`,
|
|
73
|
+
date: request.startClocks.timeStamp,
|
|
74
|
+
error: {
|
|
75
|
+
stack: safeTruncate(stack, DEFAULT_REQUEST_ERROR_RESPONSE_LENGTH_LIMIT, '...'),
|
|
76
|
+
// We don't know if the error was handled or not, so we set it to undefined
|
|
77
|
+
handling: undefined,
|
|
78
|
+
},
|
|
79
|
+
_kubesense: { debug_ids: debugIds },
|
|
80
|
+
http: {
|
|
81
|
+
method: request.method as any, // Cast resource method because of case mismatch cf issue RUMF-1152
|
|
82
|
+
status_code: request.status,
|
|
83
|
+
url: request.url,
|
|
84
|
+
},
|
|
85
|
+
status: StatusType.error,
|
|
86
|
+
origin: ErrorSource.NETWORK,
|
|
87
|
+
},
|
|
88
|
+
domainContext,
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return { stop: () => subscription.unsubscribe() }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isRejected(request: { status: number; responseType?: string }) {
|
|
96
|
+
return request.status === 0 && request.responseType !== 'opaque'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function format(type: RequestType) {
|
|
100
|
+
if (RequestType.XHR === type) {
|
|
101
|
+
return 'XHR'
|
|
102
|
+
}
|
|
103
|
+
return 'Fetch'
|
|
104
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { LogsPublicApi } from '../boot/logsPublicApi'
|
|
2
|
+
import type { StartLogsResult } from '../boot/startLogs'
|
|
3
|
+
import type { LogsInitConfiguration } from './configuration'
|
|
4
|
+
import type { AssembleHook } from './hooks'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* onInit plugin API options.
|
|
8
|
+
*
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
11
|
+
export interface OnInitOptions {
|
|
12
|
+
initConfiguration: LogsInitConfiguration
|
|
13
|
+
publicApi: LogsPublicApi
|
|
14
|
+
/**
|
|
15
|
+
* Register a callback invoked when a log event is assembled, so plugins can enrich or override
|
|
16
|
+
* log fields before they are sent. Callbacks registered in `onInit` run before any log is
|
|
17
|
+
* assembled, including logs buffered during the pre-start phase.
|
|
18
|
+
*/
|
|
19
|
+
registerAssembleEventHook: AssembleHook['register']
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* onLogsStart plugin API options.
|
|
24
|
+
*
|
|
25
|
+
* @experimental
|
|
26
|
+
*/
|
|
27
|
+
export interface OnLogsStartOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Emit a log with the same pipeline as a logger call.
|
|
30
|
+
*/
|
|
31
|
+
handleLog: StartLogsResult['handleLog']
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Plugin interface of the Logs browser SDK.
|
|
36
|
+
*
|
|
37
|
+
* The plugins API is unstable and experimental, and may change without
|
|
38
|
+
* notice. Please use only plugins provided by KubeSense matching the version of the SDK you are
|
|
39
|
+
* using.
|
|
40
|
+
*
|
|
41
|
+
* @experimental
|
|
42
|
+
*/
|
|
43
|
+
export interface LogsPlugin {
|
|
44
|
+
name: string
|
|
45
|
+
getConfigurationTelemetry?(): Record<string, unknown>
|
|
46
|
+
onInit?(options: OnInitOptions): void
|
|
47
|
+
onLogsStart?(options: OnLogsStartOptions): void
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type MethodNames = 'onInit' | 'onLogsStart'
|
|
51
|
+
type MethodParameter<MethodName extends MethodNames> = Parameters<NonNullable<LogsPlugin[MethodName]>>[0]
|
|
52
|
+
|
|
53
|
+
export function callPluginsMethod<MethodName extends MethodNames>(
|
|
54
|
+
plugins: LogsPlugin[] | undefined,
|
|
55
|
+
methodName: MethodName,
|
|
56
|
+
parameter: MethodParameter<MethodName>
|
|
57
|
+
): void
|
|
58
|
+
export function callPluginsMethod<MethodName extends MethodNames>(
|
|
59
|
+
plugins: LogsPlugin[] | undefined,
|
|
60
|
+
methodName: MethodName,
|
|
61
|
+
parameter: any
|
|
62
|
+
) {
|
|
63
|
+
if (!plugins) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
for (const plugin of plugins) {
|
|
67
|
+
const method = plugin[methodName]
|
|
68
|
+
if (method) {
|
|
69
|
+
method(parameter)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { RemoteSdkConfig } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import {
|
|
3
|
+
RawReportType,
|
|
4
|
+
getCachedSdkConfig,
|
|
5
|
+
objectValues,
|
|
6
|
+
readBoolean,
|
|
7
|
+
readSampleRate,
|
|
8
|
+
readString,
|
|
9
|
+
readStringList,
|
|
10
|
+
refreshSdkConfig,
|
|
11
|
+
} from '@kubesense/kubesense-browser-core'
|
|
12
|
+
import { ConsoleApiName } from '@kubesense/kubesense-js-core/util'
|
|
13
|
+
import type { LogsInitConfiguration } from './configuration'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Applies the dashboard-managed configuration document to the Logs init configuration.
|
|
17
|
+
*
|
|
18
|
+
* The Logs SDK reads the same cached document as RUM (they share one local-storage entry), but
|
|
19
|
+
* only consumes the `features.logs` switch and the `logs` section — RUM settings never leak
|
|
20
|
+
* into Logs, and vice versa.
|
|
21
|
+
*
|
|
22
|
+
* As in RUM, a missing or invalid field leaves the local `init()` value untouched, and
|
|
23
|
+
* identity/endpoint settings are never remotable.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export interface LogsRemoteSdkConfigurationResult {
|
|
27
|
+
initConfiguration: LogsInitConfiguration
|
|
28
|
+
/** `false` when the dashboard has switched Logs off entirely. */
|
|
29
|
+
logsEnabled: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function applyCachedLogsSdkConfiguration(
|
|
33
|
+
initConfiguration: LogsInitConfiguration
|
|
34
|
+
): LogsRemoteSdkConfigurationResult {
|
|
35
|
+
const remoteConfig = getCachedSdkConfig(initConfiguration.clientToken)
|
|
36
|
+
if (!remoteConfig) {
|
|
37
|
+
return { initConfiguration, logsEnabled: true }
|
|
38
|
+
}
|
|
39
|
+
return applyLogsSdkConfiguration(initConfiguration, remoteConfig)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function applyLogsSdkConfiguration(
|
|
43
|
+
initConfiguration: LogsInitConfiguration,
|
|
44
|
+
remoteConfig: RemoteSdkConfig
|
|
45
|
+
): LogsRemoteSdkConfigurationResult {
|
|
46
|
+
const features = remoteConfig.features as { [key: string]: unknown } | undefined
|
|
47
|
+
if (readBoolean(features, 'logs') === false) {
|
|
48
|
+
return { initConfiguration, logsEnabled: false }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const logs = remoteConfig.logs
|
|
52
|
+
if (!logs) {
|
|
53
|
+
return { initConfiguration, logsEnabled: true }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const applied: LogsInitConfiguration = { ...initConfiguration }
|
|
57
|
+
|
|
58
|
+
assign(applied, 'sessionSampleRate', readSampleRate(logs, 'sessionSampleRate'))
|
|
59
|
+
assign(applied, 'telemetrySampleRate', readSampleRate(logs, 'telemetrySampleRate'))
|
|
60
|
+
assign(applied, 'forwardErrorsToLogs', readBoolean(logs, 'forwardErrorsToLogs'))
|
|
61
|
+
assign(applied, 'trackAnonymousUser', readBoolean(logs, 'trackAnonymousUser'))
|
|
62
|
+
assign(applied, 'trackSessionAcrossSubdomains', readBoolean(logs, 'trackSessionAcrossSubdomains'))
|
|
63
|
+
assign(applied, 'allowedTrackingOrigins', readStringList(logs.allowedTrackingOrigins))
|
|
64
|
+
assign(applied, 'forwardConsoleLogs', readForwardList(logs.forwardConsoleLogs, objectValues(ConsoleApiName)))
|
|
65
|
+
assign(applied, 'forwardReports', readForwardList(logs.forwardReports, objectValues(RawReportType)))
|
|
66
|
+
|
|
67
|
+
assign(applied, 'service', readString(logs, 'service'))
|
|
68
|
+
assign(applied, 'env', readString(logs, 'env'))
|
|
69
|
+
assign(applied, 'version', readString(logs, 'version'))
|
|
70
|
+
|
|
71
|
+
return { initConfiguration: applied, logsEnabled: true }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* `forwardConsoleLogs` and `forwardReports` accept either the literal `'all'` or a subset of the
|
|
76
|
+
* known names. Unknown names are dropped rather than passed through, so a document written against
|
|
77
|
+
* a newer SDK cannot turn the option into a value this SDK will reject wholesale.
|
|
78
|
+
*/
|
|
79
|
+
function readForwardList<T extends string>(value: unknown, allowedValues: readonly T[]): T[] | 'all' | undefined {
|
|
80
|
+
if (value === 'all') {
|
|
81
|
+
return 'all'
|
|
82
|
+
}
|
|
83
|
+
const names = readStringList(value)?.filter((name): name is T => (allowedValues as readonly string[]).includes(name))
|
|
84
|
+
return names?.length ? names : undefined
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function assign<K extends keyof LogsInitConfiguration>(
|
|
88
|
+
target: LogsInitConfiguration,
|
|
89
|
+
key: K,
|
|
90
|
+
value: LogsInitConfiguration[K] | undefined
|
|
91
|
+
) {
|
|
92
|
+
if (value !== undefined) {
|
|
93
|
+
target[key] = value
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Refresh the shared cache for the next page load.
|
|
99
|
+
*
|
|
100
|
+
* When RUM and Logs both run on a page they each schedule a refresh; the requests are
|
|
101
|
+
* idempotent GETs and the last response simply wins, so no coordination is needed.
|
|
102
|
+
*/
|
|
103
|
+
export function scheduleLogsSdkConfigurationRefresh(initConfiguration: LogsInitConfiguration) {
|
|
104
|
+
return refreshSdkConfig(initConfiguration)
|
|
105
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ClocksState } from '@kubesense/kubesense-js-core/time'
|
|
2
|
+
import type { Context } from '@kubesense/kubesense-browser-core'
|
|
3
|
+
import { timeStampNow } from '@kubesense/kubesense-js-core/time'
|
|
4
|
+
import { ErrorSource, getFileFromStackTraceString, initReportObservable } from '@kubesense/kubesense-browser-core'
|
|
5
|
+
import type { LogsConfiguration } from '../configuration'
|
|
6
|
+
import type { LifeCycle } from '../lifeCycle'
|
|
7
|
+
import { LifeCycleEventType } from '../lifeCycle'
|
|
8
|
+
import { StatusType } from '../logger/isAuthorized'
|
|
9
|
+
import { createErrorFieldFromRawError } from '../createErrorFieldFromRawError'
|
|
10
|
+
|
|
11
|
+
export interface ProvidedError {
|
|
12
|
+
startClocks: ClocksState
|
|
13
|
+
error: unknown
|
|
14
|
+
context?: Context
|
|
15
|
+
handlingStack: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function startReportCollection(configuration: LogsConfiguration, lifeCycle: LifeCycle) {
|
|
19
|
+
const reportSubscription = initReportObservable(configuration.forwardReports).subscribe((rawError) => {
|
|
20
|
+
let message = rawError.message
|
|
21
|
+
let error
|
|
22
|
+
const status = rawError.originalError.type === 'deprecation' ? StatusType.warn : StatusType.error
|
|
23
|
+
|
|
24
|
+
if (status === StatusType.error) {
|
|
25
|
+
error = createErrorFieldFromRawError(rawError)
|
|
26
|
+
} else if (rawError.stack) {
|
|
27
|
+
message += ` Found in ${getFileFromStackTraceString(rawError.stack)!}`
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
lifeCycle.notify(LifeCycleEventType.RAW_LOG_COLLECTED, {
|
|
31
|
+
rawLogsEvent: {
|
|
32
|
+
date: timeStampNow(),
|
|
33
|
+
message,
|
|
34
|
+
origin: ErrorSource.REPORT,
|
|
35
|
+
error,
|
|
36
|
+
_kubesense: { debug_ids: rawError.debugIds },
|
|
37
|
+
status,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
stop: () => {
|
|
44
|
+
reportSubscription.unsubscribe()
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ErrorSource, addTelemetryDebug } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
import { timeStampNow } from '@kubesense/kubesense-js-core/time'
|
|
3
|
+
import type { LifeCycle } from './lifeCycle'
|
|
4
|
+
import { LifeCycleEventType } from './lifeCycle'
|
|
5
|
+
import { StatusType } from './logger/isAuthorized'
|
|
6
|
+
|
|
7
|
+
export function startReportError(lifeCycle: LifeCycle) {
|
|
8
|
+
return (message: string) => {
|
|
9
|
+
lifeCycle.notify(LifeCycleEventType.RAW_LOG_COLLECTED, {
|
|
10
|
+
rawLogsEvent: {
|
|
11
|
+
message,
|
|
12
|
+
date: timeStampNow(),
|
|
13
|
+
origin: ErrorSource.AGENT,
|
|
14
|
+
status: StatusType.error,
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
// monitor-until: forever, to keep an eye on the errors reported to customers
|
|
18
|
+
addTelemetryDebug('Error reported to customer', { 'error.message': message })
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ClocksState } from '@kubesense/kubesense-js-core/time'
|
|
2
|
+
import { combine } from '@kubesense/kubesense-js-core/util'
|
|
3
|
+
import type { Context, Observable, BufferedData } from '@kubesense/kubesense-browser-core'
|
|
4
|
+
import { noop, ErrorSource, BufferedDataType } from '@kubesense/kubesense-browser-core'
|
|
5
|
+
import type { LogsConfiguration } from '../configuration'
|
|
6
|
+
import type { LifeCycle } from '../lifeCycle'
|
|
7
|
+
import { LifeCycleEventType } from '../lifeCycle'
|
|
8
|
+
import { StatusType } from '../logger/isAuthorized'
|
|
9
|
+
import { createErrorFieldFromRawError } from '../createErrorFieldFromRawError'
|
|
10
|
+
|
|
11
|
+
export interface ProvidedError {
|
|
12
|
+
startClocks: ClocksState
|
|
13
|
+
error: unknown
|
|
14
|
+
context?: Context
|
|
15
|
+
handlingStack: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function startRuntimeErrorCollection(
|
|
19
|
+
configuration: LogsConfiguration,
|
|
20
|
+
lifeCycle: LifeCycle,
|
|
21
|
+
bufferedDataObservable: Observable<BufferedData>
|
|
22
|
+
) {
|
|
23
|
+
if (!configuration.forwardErrorsToLogs) {
|
|
24
|
+
return { stop: noop }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const rawErrorSubscription = bufferedDataObservable.subscribe((bufferedData) => {
|
|
28
|
+
if (bufferedData.type === BufferedDataType.RUNTIME_ERROR) {
|
|
29
|
+
const error = bufferedData.data
|
|
30
|
+
lifeCycle.notify(LifeCycleEventType.RAW_LOG_COLLECTED, {
|
|
31
|
+
rawLogsEvent: combine(
|
|
32
|
+
{
|
|
33
|
+
message: error.message,
|
|
34
|
+
date: error.startClocks.timeStamp,
|
|
35
|
+
error: createErrorFieldFromRawError(error),
|
|
36
|
+
_kubesense: { debug_ids: error.debugIds },
|
|
37
|
+
origin: ErrorSource.SOURCE,
|
|
38
|
+
status: StatusType.error,
|
|
39
|
+
},
|
|
40
|
+
error.context
|
|
41
|
+
),
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
stop: () => {
|
|
48
|
+
rawErrorSubscription.unsubscribe()
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ErrorSource } from '@kubesense/kubesense-browser-core'
|
|
2
|
+
|
|
3
|
+
export type LogsEventDomainContext<T extends ErrorSource = any> = T extends typeof ErrorSource.NETWORK
|
|
4
|
+
? NetworkLogsEventDomainContext
|
|
5
|
+
: T extends typeof ErrorSource.CONSOLE
|
|
6
|
+
? ConsoleLogsEventDomainContext
|
|
7
|
+
: T extends typeof ErrorSource.LOGGER
|
|
8
|
+
? LoggerLogsEventDomainContext
|
|
9
|
+
: undefined
|
|
10
|
+
|
|
11
|
+
export interface NetworkLogsEventDomainContext {
|
|
12
|
+
handlingStack?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ConsoleLogsEventDomainContext {
|
|
16
|
+
handlingStack: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface LoggerLogsEventDomainContext {
|
|
20
|
+
handlingStack: string
|
|
21
|
+
}
|