@dasasian/firebase-structured-logger 0.1.0

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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +228 -0
  3. package/dist/client/breadcrumbs.d.ts +15 -0
  4. package/dist/client/breadcrumbs.d.ts.map +1 -0
  5. package/dist/client/breadcrumbs.js +52 -0
  6. package/dist/client/breadcrumbs.js.map +1 -0
  7. package/dist/client/errorHandler.d.ts +5 -0
  8. package/dist/client/errorHandler.d.ts.map +1 -0
  9. package/dist/client/errorHandler.js +19 -0
  10. package/dist/client/errorHandler.js.map +1 -0
  11. package/dist/client/index.d.ts +6 -0
  12. package/dist/client/index.d.ts.map +1 -0
  13. package/dist/client/index.js +16 -0
  14. package/dist/client/index.js.map +1 -0
  15. package/dist/client/logger.d.ts +40 -0
  16. package/dist/client/logger.d.ts.map +1 -0
  17. package/dist/client/logger.js +199 -0
  18. package/dist/client/logger.js.map +1 -0
  19. package/dist/client/rateLimiter.d.ts +12 -0
  20. package/dist/client/rateLimiter.d.ts.map +1 -0
  21. package/dist/client/rateLimiter.js +80 -0
  22. package/dist/client/rateLimiter.js.map +1 -0
  23. package/dist/functions/index.d.ts +12 -0
  24. package/dist/functions/index.d.ts.map +1 -0
  25. package/dist/functions/index.js +21 -0
  26. package/dist/functions/index.js.map +1 -0
  27. package/dist/functions/logHandler.d.ts +27 -0
  28. package/dist/functions/logHandler.d.ts.map +1 -0
  29. package/dist/functions/logHandler.js +137 -0
  30. package/dist/functions/logHandler.js.map +1 -0
  31. package/dist/functions/logger.d.ts +32 -0
  32. package/dist/functions/logger.d.ts.map +1 -0
  33. package/dist/functions/logger.js +253 -0
  34. package/dist/functions/logger.js.map +1 -0
  35. package/dist/functions/requestLogger.d.ts +30 -0
  36. package/dist/functions/requestLogger.d.ts.map +1 -0
  37. package/dist/functions/requestLogger.js +45 -0
  38. package/dist/functions/requestLogger.js.map +1 -0
  39. package/dist/functions/sourceMapCache.d.ts +9 -0
  40. package/dist/functions/sourceMapCache.d.ts.map +1 -0
  41. package/dist/functions/sourceMapCache.js +107 -0
  42. package/dist/functions/sourceMapCache.js.map +1 -0
  43. package/dist/functions/symbolicate.d.ts +31 -0
  44. package/dist/functions/symbolicate.d.ts.map +1 -0
  45. package/dist/functions/symbolicate.js +112 -0
  46. package/dist/functions/symbolicate.js.map +1 -0
  47. package/dist/shared/types.d.ts +36 -0
  48. package/dist/shared/types.d.ts.map +1 -0
  49. package/dist/shared/types.js +3 -0
  50. package/dist/shared/types.js.map +1 -0
  51. package/dist/tools/index.d.ts +3 -0
  52. package/dist/tools/index.d.ts.map +1 -0
  53. package/dist/tools/index.js +152 -0
  54. package/dist/tools/index.js.map +1 -0
  55. package/dist/tools/installSkills.d.ts +6 -0
  56. package/dist/tools/installSkills.d.ts.map +1 -0
  57. package/dist/tools/installSkills.js +89 -0
  58. package/dist/tools/installSkills.js.map +1 -0
  59. package/dist/tools/packDeploy.d.ts +15 -0
  60. package/dist/tools/packDeploy.d.ts.map +1 -0
  61. package/dist/tools/packDeploy.js +148 -0
  62. package/dist/tools/packDeploy.js.map +1 -0
  63. package/dist/tools/uploadSourceMaps.d.ts +9 -0
  64. package/dist/tools/uploadSourceMaps.d.ts.map +1 -0
  65. package/dist/tools/uploadSourceMaps.js +120 -0
  66. package/dist/tools/uploadSourceMaps.js.map +1 -0
  67. package/package.json +103 -0
  68. package/skills/logs/SKILL.md +185 -0
  69. package/skills/query-logs/SKILL.md +93 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/client/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface RateLimitConfig {
2
+ sessionLimit?: number;
3
+ duplicateLimit?: number;
4
+ storageKey?: string;
5
+ }
6
+ export declare function configureRateLimiter(options: RateLimitConfig): void;
7
+ export declare function canLogEvent(): boolean;
8
+ export declare function canLogError(error: Error | string, screen?: string, activity?: string): boolean;
9
+ export declare function recordLog(): void;
10
+ export declare function recordError(error: Error | string, screen?: string, activity?: string): void;
11
+ export declare function resetRateLimiter(): void;
12
+ //# sourceMappingURL=rateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAaD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEnE;AA4BD,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAYT;AAED,wBAAgB,SAAS,IAAI,IAAI,CAIhC;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,GAAG,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAMN;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureRateLimiter = configureRateLimiter;
4
+ exports.canLogEvent = canLogEvent;
5
+ exports.canLogError = canLogError;
6
+ exports.recordLog = recordLog;
7
+ exports.recordError = recordError;
8
+ exports.resetRateLimiter = resetRateLimiter;
9
+ const DEFAULT_SESSION_LIMIT = 50;
10
+ const DEFAULT_DUPLICATE_LIMIT = 3;
11
+ const DEFAULT_STORAGE_KEY = 'fsl_ratelimit';
12
+ let config = {
13
+ sessionLimit: DEFAULT_SESSION_LIMIT,
14
+ duplicateLimit: DEFAULT_DUPLICATE_LIMIT,
15
+ storageKey: DEFAULT_STORAGE_KEY,
16
+ };
17
+ function configureRateLimiter(options) {
18
+ config = { ...config, ...options };
19
+ }
20
+ function getState() {
21
+ try {
22
+ const stored = sessionStorage.getItem(config.storageKey);
23
+ return stored ? JSON.parse(stored) : { logCount: 0, errorSignatures: {} };
24
+ }
25
+ catch {
26
+ return { logCount: 0, errorSignatures: {} };
27
+ }
28
+ }
29
+ function saveState(state) {
30
+ try {
31
+ sessionStorage.setItem(config.storageKey, JSON.stringify(state));
32
+ }
33
+ catch {
34
+ // Silently fail if sessionStorage is full
35
+ }
36
+ }
37
+ function getErrorSignature(error, screen, activity) {
38
+ const str = error instanceof Error ? `${error.name}:${error.message}` : String(error);
39
+ return `${str}|${screen ?? ''}|${activity ?? ''}`;
40
+ }
41
+ function canLogEvent() {
42
+ return getState().logCount < config.sessionLimit;
43
+ }
44
+ function canLogError(error, screen, activity) {
45
+ const state = getState();
46
+ if (state.logCount >= config.sessionLimit) {
47
+ console.warn('[fsl] Session log limit reached');
48
+ return false;
49
+ }
50
+ const sig = getErrorSignature(error, screen, activity);
51
+ if ((state.errorSignatures[sig] ?? 0) >= config.duplicateLimit) {
52
+ console.warn(`[fsl] Duplicate error suppressed: ${sig}`);
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+ function recordLog() {
58
+ const state = getState();
59
+ state.logCount++;
60
+ saveState(state);
61
+ }
62
+ function recordError(error, screen, activity) {
63
+ const state = getState();
64
+ const sig = getErrorSignature(error, screen, activity);
65
+ state.errorSignatures[sig] = (state.errorSignatures[sig] ?? 0) + 1;
66
+ state.logCount++;
67
+ saveState(state);
68
+ }
69
+ function resetRateLimiter() {
70
+ try {
71
+ sessionStorage.removeItem(config.storageKey);
72
+ }
73
+ catch {
74
+ // Silently fail
75
+ }
76
+ }
77
+ if (typeof window !== 'undefined') {
78
+ window.addEventListener('beforeunload', resetRateLimiter);
79
+ }
80
+ //# sourceMappingURL=rateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { LogWriter } from './logger';
2
+ export { initLogger } from './logger';
3
+ export type { LogWriter } from './logger';
4
+ export { initRequestLogger, getLogger } from './requestLogger';
5
+ export { createClientLogHandler, createClientLogFunction } from './logHandler';
6
+ export type { ClientLogHandlerConfig } from './logHandler';
7
+ export type { LogSeverity, LogPayload, BaseLabels } from '../shared/types';
8
+ export declare const logError: (...args: Parameters<LogWriter["error"]>) => void;
9
+ export declare const logWarn: (...args: Parameters<LogWriter["warning"]>) => void;
10
+ export declare const logInfo: (...args: Parameters<LogWriter["info"]>) => void;
11
+ export declare const logDebug: (...args: Parameters<LogWriter["debug"]>) => void;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAC9E,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC1D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE1E,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA;AACrG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAG,IAAoC,CAAA;AACxG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAG,IAAiC,CAAA;AAClG,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logDebug = exports.logInfo = exports.logWarn = exports.logError = exports.createClientLogFunction = exports.createClientLogHandler = exports.getLogger = exports.initRequestLogger = exports.initLogger = void 0;
4
+ const requestLogger_1 = require("./requestLogger");
5
+ var logger_1 = require("./logger");
6
+ Object.defineProperty(exports, "initLogger", { enumerable: true, get: function () { return logger_1.initLogger; } });
7
+ var requestLogger_2 = require("./requestLogger");
8
+ Object.defineProperty(exports, "initRequestLogger", { enumerable: true, get: function () { return requestLogger_2.initRequestLogger; } });
9
+ Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return requestLogger_2.getLogger; } });
10
+ var logHandler_1 = require("./logHandler");
11
+ Object.defineProperty(exports, "createClientLogHandler", { enumerable: true, get: function () { return logHandler_1.createClientLogHandler; } });
12
+ Object.defineProperty(exports, "createClientLogFunction", { enumerable: true, get: function () { return logHandler_1.createClientLogFunction; } });
13
+ const logError = (...args) => (0, requestLogger_1.getLogger)().error(...args);
14
+ exports.logError = logError;
15
+ const logWarn = (...args) => (0, requestLogger_1.getLogger)().warning(...args);
16
+ exports.logWarn = logWarn;
17
+ const logInfo = (...args) => (0, requestLogger_1.getLogger)().info(...args);
18
+ exports.logInfo = logInfo;
19
+ const logDebug = (...args) => (0, requestLogger_1.getLogger)().debug(...args);
20
+ exports.logDebug = logDebug;
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":";;;AAAA,mDAA2C;AAG3C,mCAAqC;AAA5B,oGAAA,UAAU,OAAA;AAEnB,iDAA8D;AAArD,kHAAA,iBAAiB,OAAA;AAAE,0GAAA,SAAS,OAAA;AACrC,2CAA8E;AAArE,oHAAA,sBAAsB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAIjD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAoC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AAAxF,QAAA,QAAQ,YAAgF;AAC9F,MAAM,OAAO,GAAG,CAAC,GAAG,IAAsC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;AAA3F,QAAA,OAAO,WAAoF;AACjG,MAAM,OAAO,GAAG,CAAC,GAAG,IAAmC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;AAArF,QAAA,OAAO,WAA8E;AAC3F,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAoC,EAAQ,EAAE,CAAC,IAAA,yBAAS,GAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;AAAxF,QAAA,QAAQ,YAAgF"}
@@ -0,0 +1,27 @@
1
+ import { type CallableRequest } from 'firebase-functions/v2/https';
2
+ import type { LogPayload } from '../shared/types';
3
+ export interface ClientLogHandlerConfig {
4
+ bucketName?: string;
5
+ cors?: boolean | string | string[];
6
+ maxInstances?: number;
7
+ }
8
+ /**
9
+ * Create an onCall handler that receives LogPayload from the client,
10
+ * symbolicates stack traces, and writes structured entries to Cloud Logging.
11
+ *
12
+ * @example
13
+ * export const logFrontendEvent = onCall(createClientLogHandler({ bucketName: 'my-bucket' }))
14
+ */
15
+ export declare function createClientLogHandler(config: ClientLogHandlerConfig): (request: CallableRequest<LogPayload>) => Promise<void>;
16
+ /**
17
+ * Convenience factory that wraps createClientLogHandler in onCall.
18
+ * Use when you want a ready-to-export Cloud Function.
19
+ *
20
+ * @example
21
+ * export const logFrontendEvent = createClientLogFunction({ bucketName: 'my-bucket' })
22
+ */
23
+ export declare function createClientLogFunction(config: ClientLogHandlerConfig & {
24
+ cors?: boolean | string | string[];
25
+ maxInstances?: number;
26
+ }): import("firebase-functions/v2/https").CallableFunction<LogPayload, Promise<void>, unknown>;
27
+ //# sourceMappingURL=logHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logHandler.d.ts","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AASjD,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAgGD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,IAGrD,SAAS,eAAe,CAAC,UAAU,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAgCnE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,8FAM/F"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createClientLogHandler = createClientLogHandler;
4
+ exports.createClientLogFunction = createClientLogFunction;
5
+ const https_1 = require("firebase-functions/v2/https");
6
+ const logger_1 = require("./logger");
7
+ const sourceMapCache_1 = require("./sourceMapCache");
8
+ const symbolicate_1 = require("./symbolicate");
9
+ const VALID_SEVERITIES = new Set(['ERROR', 'WARNING', 'INFO', 'DEBUG']);
10
+ /**
11
+ * Extract the bundle filename (e.g. "index-DnZ05f3M.js") from a frame URL.
12
+ */
13
+ function bundleFileFromUrl(url) {
14
+ const match = url.match(/\/([^/]+\.js)(?:[?#].*)?$/);
15
+ return match ? match[1] : null;
16
+ }
17
+ /**
18
+ * Attempt to symbolicate a minified error stack trace using source maps.
19
+ * Loads source maps per-bundle so multiple chunks are handled correctly.
20
+ */
21
+ async function symbolicateError(releaseId, error) {
22
+ if (!error?.stack)
23
+ return error;
24
+ try {
25
+ const frames = (0, symbolicate_1.parseStackTrace)(error.stack);
26
+ // Collect unique bundle filenames referenced across all frames
27
+ const bundleFiles = new Set();
28
+ for (const frame of frames) {
29
+ if (frame.fileName) {
30
+ const bundle = bundleFileFromUrl(frame.fileName);
31
+ if (bundle)
32
+ bundleFiles.add(bundle);
33
+ }
34
+ }
35
+ if (bundleFiles.size === 0)
36
+ return error;
37
+ // Load source map for each unique bundle (getSourceMap handles caching)
38
+ const sourceMaps = new Map();
39
+ await Promise.all(Array.from(bundleFiles).map(async (bundle) => {
40
+ const map = await (0, sourceMapCache_1.getSourceMap)(releaseId, bundle);
41
+ if (map)
42
+ sourceMaps.set(bundle, map);
43
+ }));
44
+ if (sourceMaps.size === 0)
45
+ return error;
46
+ // Symbolicate each frame with its bundle's source map
47
+ const symbolicated = frames.map((frame) => {
48
+ if (!frame.fileName || !frame.lineNumber || !frame.columnNumber)
49
+ return frame;
50
+ const bundle = bundleFileFromUrl(frame.fileName);
51
+ if (!bundle)
52
+ return frame;
53
+ const sourceMap = sourceMaps.get(bundle);
54
+ if (!sourceMap)
55
+ return frame;
56
+ const result = (0, symbolicate_1.symbolicate)(sourceMap, frame.lineNumber, frame.columnNumber);
57
+ if (!result)
58
+ return frame;
59
+ return {
60
+ ...frame,
61
+ fileName: result.source,
62
+ lineNumber: result.line,
63
+ columnNumber: result.column,
64
+ functionName: result.name ?? frame.functionName,
65
+ };
66
+ });
67
+ return { ...error, stack: (0, symbolicate_1.formatStackTrace)(symbolicated) };
68
+ }
69
+ catch (err) {
70
+ console.warn('[fsl] Symbolication failed:', err);
71
+ }
72
+ return error;
73
+ }
74
+ /**
75
+ * Strip null/undefined labels and convert all values to strings for Cloud Logging.
76
+ */
77
+ function cleanLabels(labels) {
78
+ if (!labels)
79
+ return {};
80
+ const cleaned = {};
81
+ for (const [key, value] of Object.entries(labels)) {
82
+ if (value !== null && value !== undefined) {
83
+ cleaned[key] = String(value);
84
+ }
85
+ }
86
+ return cleaned;
87
+ }
88
+ /**
89
+ * Create an onCall handler that receives LogPayload from the client,
90
+ * symbolicates stack traces, and writes structured entries to Cloud Logging.
91
+ *
92
+ * @example
93
+ * export const logFrontendEvent = onCall(createClientLogHandler({ bucketName: 'my-bucket' }))
94
+ */
95
+ function createClientLogHandler(config) {
96
+ if (config.bucketName)
97
+ (0, sourceMapCache_1.configureSourceMapBucket)(config.bucketName);
98
+ return async (request) => {
99
+ const { message, severity, labels, jsonPayload } = request.data;
100
+ if (!message || !severity) {
101
+ throw new https_1.HttpsError('invalid-argument', 'Missing message or severity');
102
+ }
103
+ if (!VALID_SEVERITIES.has(severity)) {
104
+ throw new https_1.HttpsError('invalid-argument', `Invalid severity: ${severity}`);
105
+ }
106
+ const isEmulator = process.env.FUNCTIONS_EMULATOR === 'true';
107
+ try {
108
+ let processedError = jsonPayload?.error;
109
+ if (processedError?.stack && !isEmulator) {
110
+ const releaseId = labels?.releaseId ?? 'unknown';
111
+ processedError = await symbolicateError(releaseId, processedError);
112
+ }
113
+ (0, logger_1.writeLog)({
114
+ message,
115
+ severity,
116
+ labels: cleanLabels(labels),
117
+ jsonPayload: { ...jsonPayload, error: processedError },
118
+ attachments: request.data.attachments,
119
+ });
120
+ }
121
+ catch (err) {
122
+ console.error('[fsl] Error processing client log:', err);
123
+ throw new https_1.HttpsError('internal', 'Failed to process log');
124
+ }
125
+ };
126
+ }
127
+ /**
128
+ * Convenience factory that wraps createClientLogHandler in onCall.
129
+ * Use when you want a ready-to-export Cloud Function.
130
+ *
131
+ * @example
132
+ * export const logFrontendEvent = createClientLogFunction({ bucketName: 'my-bucket' })
133
+ */
134
+ function createClientLogFunction(config) {
135
+ return (0, https_1.onCall)({ cors: config.cors ?? true, maxInstances: config.maxInstances ?? 1 }, createClientLogHandler(config));
136
+ }
137
+ //# sourceMappingURL=logHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logHandler.js","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":";;AAqHA,wDAmCC;AASD,0DAOC;AAxKD,uDAAsF;AAEtF,qCAAmC;AACnC,qDAAyE;AACzE,+CAIsB;AAQtB,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AASvE;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAC7B,SAAiB,EACjB,KAA+B;IAE/B,IAAI,CAAC,KAAK,EAAE,KAAK;QAAE,OAAO,KAAK,CAAA;IAE/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,6BAAe,EAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE3C,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;QACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAChD,IAAI,MAAM;oBAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QAED,IAAI,WAAW,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAExC,wEAAwE;QACxE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoD,CAAA;QAC9E,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,GAAG,GAAG,MAAM,IAAA,6BAAY,EAAC,SAAS,EAAE,MAAM,CAAC,CAAA;YACjD,IAAI,GAAG;gBAAE,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,CAAC,CAAC,CACH,CAAA;QAED,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAEvC,sDAAsD;QACtD,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACxC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,YAAY;gBAAE,OAAO,KAAK,CAAA;YAC7E,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAChD,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAA;YACzB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACxC,IAAI,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAA;YAC5B,MAAM,MAAM,GAAG,IAAA,yBAAW,EAAC,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;YAC3E,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAA;YACzB,OAAO;gBACL,GAAG,KAAK;gBACR,QAAQ,EAAE,MAAM,CAAC,MAAM;gBACvB,UAAU,EAAE,MAAM,CAAC,IAAI;gBACvB,YAAY,EAAE,MAAM,CAAC,MAAM;gBAC3B,YAAY,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,YAAY;aAChD,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAA,8BAAgB,EAAC,YAAY,CAAC,EAAE,CAAA;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,MAAwC;IAExC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAA;IACtB,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,MAA8B;IACnE,IAAI,MAAM,CAAC,UAAU;QAAE,IAAA,yCAAwB,EAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAElE,OAAO,KAAK,EAAE,OAAoC,EAAiB,EAAE;QACnE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAA;QAE/D,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,kBAAU,CAAC,kBAAkB,EAAE,6BAA6B,CAAC,CAAA;QACzE,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,kBAAU,CAAC,kBAAkB,EAAE,qBAAqB,QAAQ,EAAE,CAAC,CAAA;QAC3E,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAA;QAE5D,IAAI,CAAC;YACH,IAAI,cAAc,GAAG,WAAW,EAAE,KAAK,CAAA;YACvC,IAAI,cAAc,EAAE,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,SAAS,CAAA;gBAChD,cAAc,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;YACpE,CAAC;YAED,IAAA,iBAAQ,EAAC;gBACP,OAAO;gBACP,QAAQ;gBACR,MAAM,EAAE,WAAW,CAAC,MAAM,CAAyB;gBACnD,WAAW,EAAE,EAAE,GAAG,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE;gBACtD,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW;aACtC,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAA;YACxD,MAAM,IAAI,kBAAU,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,uBAAuB,CACrC,MAA8F;IAE9F,OAAO,IAAA,cAAM,EACX,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,EACrE,sBAAsB,CAAC,MAAM,CAAC,CAC/B,CAAA;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { LogSeverity, LogPayload } from "../shared/types";
2
+ interface FunctionsLoggerConfig {
3
+ appId: string;
4
+ logLocalDir?: string;
5
+ logMaxRecordsPerFile?: number;
6
+ logMaxRotatedFiles?: number;
7
+ minSeverity?: LogSeverity;
8
+ }
9
+ /**
10
+ * Initialize the functions-side logger.
11
+ * Call once at module load (before any onCall handlers run).
12
+ */
13
+ export declare function initLogger(config: FunctionsLoggerConfig): void;
14
+ /**
15
+ * Write a structured log entry. Transport depends on environment.
16
+ */
17
+ export declare function writeLog(payload: LogPayload & {
18
+ functionName?: string;
19
+ requestId?: string;
20
+ }): void;
21
+ /**
22
+ * Convenience wrapper that builds a logger object for a given label set.
23
+ */
24
+ export declare function createLogWriter(baseLabels: Record<string, string | undefined>): {
25
+ error(raw: unknown, labels?: Record<string, string | undefined>, context?: Record<string, unknown>, attachments?: Record<string, string | Buffer>): void;
26
+ info(message: string, labels?: Record<string, string | undefined>, context?: Record<string, unknown>, attachments?: Record<string, string | Buffer>): void;
27
+ warning(message: string, labels?: Record<string, string | undefined>, context?: Record<string, unknown>, attachments?: Record<string, string | Buffer>): void;
28
+ debug(message: string, labels?: Record<string, string | undefined>, context?: Record<string, unknown>, attachments?: Record<string, string | Buffer>): void;
29
+ };
30
+ export type LogWriter = ReturnType<typeof createLogWriter>;
31
+ export type { LogSeverity };
32
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/functions/logger.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM/D,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAYD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAQ9D;AA2DD;;GAEG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,UAAU,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,IAAI,CAuEN;AAaD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;eASrC,OAAO,WACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,IAAI;kBAsBI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,IAAI;qBAUI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,IAAI;mBAUI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,IAAI;EAUV;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAG3D,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.initLogger = initLogger;
37
+ exports.writeLog = writeLog;
38
+ exports.createLogWriter = createLogWriter;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const logger_1 = require("firebase-functions/logger");
42
+ const ulid_1 = require("ulid");
43
+ const storage_1 = require("firebase-admin/storage");
44
+ const sourceMapCache_1 = require("./sourceMapCache");
45
+ const IS_EMULATOR = process.env.FUNCTIONS_EMULATOR === "true";
46
+ const LOG_FILENAME = "dev.jsonl";
47
+ const SEVERITY_ORDER = {
48
+ ERROR: 0,
49
+ WARNING: 1,
50
+ INFO: 2,
51
+ DEBUG: 3,
52
+ };
53
+ let globalConfig = null;
54
+ let currentRecordCount = 0;
55
+ /**
56
+ * Initialize the functions-side logger.
57
+ * Call once at module load (before any onCall handlers run).
58
+ */
59
+ function initLogger(config) {
60
+ globalConfig = config;
61
+ currentRecordCount = 0;
62
+ if (IS_EMULATOR && config.logLocalDir) {
63
+ fs.mkdirSync(config.logLocalDir, { recursive: true });
64
+ rotateLogFile(config.logLocalDir, config.logMaxRotatedFiles ?? 5);
65
+ }
66
+ }
67
+ /**
68
+ * Rotate the current log file to a timestamped backup, delete oldest files beyond limit.
69
+ */
70
+ function rotateLogFile(logDir, maxRotatedFiles) {
71
+ const current = path.join(logDir, LOG_FILENAME);
72
+ try {
73
+ // The functions emulator spawns multiple worker processes that each call
74
+ // initLogger() on startup. existsSync + renameSync is a TOCTOU race:
75
+ // a parallel worker can rename the file between our check and our rename.
76
+ // Attempt the rename and swallow ENOENT — it means another worker already rotated.
77
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
78
+ try {
79
+ fs.renameSync(current, path.join(logDir, `dev-${timestamp}.jsonl`));
80
+ }
81
+ catch (err) {
82
+ if (err.code !== "ENOENT")
83
+ throw err;
84
+ // Another worker rotated first (or no previous log file to rotate) — fine
85
+ }
86
+ // Delete oldest rotated files beyond limit
87
+ const rotated = fs
88
+ .readdirSync(logDir)
89
+ .filter((f) => f.startsWith("dev-") && f.endsWith(".jsonl"))
90
+ .sort(); // ISO timestamps sort lexicographically = chronologically
91
+ const toDelete = rotated.slice(0, Math.max(0, rotated.length - maxRotatedFiles));
92
+ for (const f of toDelete) {
93
+ try {
94
+ fs.unlinkSync(path.join(logDir, f));
95
+ }
96
+ catch (err) {
97
+ if (err.code !== "ENOENT")
98
+ throw err;
99
+ // Another worker already deleted it — fine
100
+ }
101
+ }
102
+ }
103
+ catch (err) {
104
+ console.warn("[fsl] Failed to rotate log file:", err);
105
+ }
106
+ }
107
+ async function uploadLogAttachments(logId, logAttachments) {
108
+ const bucketName = (0, sourceMapCache_1.getConfiguredBucket)();
109
+ const bucket = bucketName
110
+ ? (0, storage_1.getStorage)().bucket(bucketName)
111
+ : (0, storage_1.getStorage)().bucket();
112
+ await Promise.all(Object.entries(logAttachments).map(async ([name, data]) => {
113
+ const file = bucket.file(`logAttachments/${logId}/${name}`);
114
+ await file.save(Buffer.from(data, "base64"));
115
+ }));
116
+ }
117
+ /**
118
+ * Write a structured log entry. Transport depends on environment.
119
+ */
120
+ function writeLog(payload) {
121
+ const minSeverity = globalConfig?.minSeverity ?? (IS_EMULATOR ? "DEBUG" : "WARNING");
122
+ if (SEVERITY_ORDER[payload.severity] > SEVERITY_ORDER[minSeverity])
123
+ return;
124
+ const logId = (0, ulid_1.ulid)();
125
+ const hasAttachments = payload.attachments && Object.keys(payload.attachments).length > 0;
126
+ const labels = {
127
+ ...payload.labels,
128
+ logId,
129
+ ...(hasAttachments ? { hasAttachments: "true" } : {}),
130
+ };
131
+ if (hasAttachments) {
132
+ uploadLogAttachments(logId, payload.attachments).catch((err) => {
133
+ console.warn("[fsl] Log attachment upload failed:", err);
134
+ });
135
+ }
136
+ if (IS_EMULATOR) {
137
+ if (globalConfig?.logLocalDir) {
138
+ try {
139
+ const entry = {
140
+ timestamp: new Date().toISOString(),
141
+ severity: payload.severity,
142
+ message: payload.message,
143
+ labels,
144
+ jsonPayload: payload.jsonPayload,
145
+ ...(payload.functionName
146
+ ? { functionName: payload.functionName }
147
+ : {}),
148
+ ...(payload.requestId ? { requestId: payload.requestId } : {}),
149
+ };
150
+ const maxRecords = globalConfig.logMaxRecordsPerFile ?? 2000;
151
+ const maxRotated = globalConfig.logMaxRotatedFiles ?? 5;
152
+ if (currentRecordCount >= maxRecords) {
153
+ rotateLogFile(globalConfig.logLocalDir, maxRotated);
154
+ currentRecordCount = 0;
155
+ }
156
+ const logFile = path.join(globalConfig.logLocalDir, LOG_FILENAME);
157
+ fs.appendFileSync(logFile, JSON.stringify(entry) + "\n", "utf-8");
158
+ currentRecordCount++;
159
+ }
160
+ catch (err) {
161
+ console.warn("[fsl] Failed to write to log file:", err);
162
+ }
163
+ }
164
+ // Also write to console for immediate visibility
165
+ const consoleFn = payload.severity === "ERROR"
166
+ ? console.error
167
+ : payload.severity === "WARNING"
168
+ ? console.warn
169
+ : payload.severity === "DEBUG"
170
+ ? console.debug
171
+ : console.log;
172
+ consoleFn(`[${payload.severity}] ${payload.message}`, labels);
173
+ return;
174
+ }
175
+ // Production: use firebase-functions/logger write() directly, bypassing entryFromArgs.
176
+ // This avoids server-side stack injection and jsonPayload nesting, while preserving
177
+ // automatic trace context injection for request correlation in Cloud Logging.
178
+ (0, logger_1.write)({
179
+ severity: payload.severity,
180
+ message: payload.message,
181
+ labels: labels,
182
+ ...payload.jsonPayload,
183
+ });
184
+ }
185
+ function logAttachmentsToBase64(logAttachments) {
186
+ if (!logAttachments)
187
+ return undefined;
188
+ const result = {};
189
+ for (const [k, v] of Object.entries(logAttachments)) {
190
+ result[k] = v instanceof Buffer ? v.toString("base64") : v;
191
+ }
192
+ return result;
193
+ }
194
+ /**
195
+ * Convenience wrapper that builds a logger object for a given label set.
196
+ */
197
+ function createLogWriter(baseLabels) {
198
+ const merge = (extra) => ({
199
+ ...baseLabels,
200
+ ...extra,
201
+ });
202
+ return {
203
+ error(raw, labels, context, attachments) {
204
+ const error = raw instanceof Error ? raw : new Error(String(raw));
205
+ writeLog({
206
+ message: error.message,
207
+ severity: "ERROR",
208
+ labels: merge({
209
+ errorType: error.name,
210
+ ...labels,
211
+ }),
212
+ jsonPayload: {
213
+ context,
214
+ error: {
215
+ message: error.message,
216
+ stack: error.stack,
217
+ name: error.name,
218
+ cause: error.cause !== undefined ? String(error.cause) : undefined,
219
+ },
220
+ },
221
+ attachments: logAttachmentsToBase64(attachments),
222
+ });
223
+ },
224
+ info(message, labels, context, attachments) {
225
+ writeLog({
226
+ message,
227
+ severity: "INFO",
228
+ labels: merge(labels),
229
+ jsonPayload: { context },
230
+ attachments: logAttachmentsToBase64(attachments),
231
+ });
232
+ },
233
+ warning(message, labels, context, attachments) {
234
+ writeLog({
235
+ message,
236
+ severity: "WARNING",
237
+ labels: merge(labels),
238
+ jsonPayload: { context },
239
+ attachments: logAttachmentsToBase64(attachments),
240
+ });
241
+ },
242
+ debug(message, labels, context, attachments) {
243
+ writeLog({
244
+ message,
245
+ severity: "DEBUG",
246
+ labels: merge(labels),
247
+ jsonPayload: { context },
248
+ attachments: logAttachmentsToBase64(attachments),
249
+ });
250
+ },
251
+ };
252
+ }
253
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/functions/logger.ts"],"names":[],"mappings":"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"}