@genkit-ai/google-cloud
Version:
Genkit AI framework plugin for Google Cloud Platform including Firestore trace/state store and deployment helpers for Cloud Functions for Firebase.
1 lines • 5.79 kB
Source Map (JSON)
{"version":3,"sources":["../src/gcpLogger.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggingWinston } from '@google-cloud/logging-winston';\nimport { getCurrentEnv } from 'genkit';\nimport { logger } from 'genkit/logging';\nimport type { Writable } from 'stream';\nimport type { GcpTelemetryConfig } from './types.js';\nimport { loggingDenied, loggingDeniedHelpText } from './utils.js';\n\n/**\n * Additional streams for writing log data to. Useful for unit testing.\n */\nlet additionalStream: Writable;\nlet useJsonFormatOverride = false;\n\n/**\n * Provides a logger for exporting Genkit debug logs to GCP Cloud\n * logs.\n */\nexport class GcpLogger {\n constructor(private readonly config: GcpTelemetryConfig) {}\n\n async getLogger(env: string) {\n // Dynamically importing winston here more strictly controls\n // the import order relative to registering instrumentation\n // with OpenTelemetry. Incorrect import order will trigger\n // an internal OT warning and will result in logs not being\n // associated with correct spans/traces.\n const winston = await import('winston');\n\n const format =\n useJsonFormatOverride || this.shouldExport(env)\n ? { format: winston.format.json() }\n : {\n format: winston.format.printf((info): string => {\n return `[${info.level}] ${info.message}`;\n }),\n };\n\n const transports: any[] = [];\n transports.push(\n this.shouldExport(env)\n ? new LoggingWinston({\n labels: { module: 'genkit' },\n prefix: 'genkit',\n logName: 'genkit_log',\n projectId: this.config.projectId,\n credentials: this.config.credentials,\n autoRetry: true,\n defaultCallback: await this.getErrorHandler(),\n })\n : new winston.transports.Console()\n );\n if (additionalStream) {\n transports.push(\n new winston.transports.Stream({ stream: additionalStream })\n );\n }\n return winston.createLogger({\n transports: transports,\n ...format,\n exceptionHandlers: [new winston.transports.Console()],\n });\n }\n\n private async getErrorHandler(): Promise<(err: Error | null) => void> {\n // only log the first time\n let instructionsLogged = false;\n const helpInstructions = await loggingDeniedHelpText();\n\n return async (err: Error | null) => {\n // Use the defaultLogger so that logs don't get swallowed by\n // the open telemetry exporter\n const defaultLogger = logger.defaultLogger;\n if (err && loggingDenied(err)) {\n if (!instructionsLogged) {\n instructionsLogged = true;\n defaultLogger.error(\n `Unable to send logs to Google Cloud: ${err.message}\\n\\n${helpInstructions}\\n`\n );\n }\n } else if (err) {\n defaultLogger.error(`Unable to send logs to Google Cloud: ${err}`);\n }\n\n if (err) {\n // Assume the logger is compromised, and we need a new one\n // Reinitialize the genkit logger with a new instance with the same config\n logger.init(\n await new GcpLogger(this.config).getLogger(getCurrentEnv())\n );\n defaultLogger.info('Initialized a new GcpLogger.');\n }\n };\n }\n\n private shouldExport(env?: string) {\n return this.config.export;\n }\n}\n\n/** @hidden */\nexport function __addTransportStreamForTesting(stream: Writable) {\n additionalStream = stream;\n}\n\n/** @hidden */\nexport function __useJsonFormatForTesting() {\n useJsonFormatOverride = true;\n}\n"],"mappings":"AAgBA,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AAGvB,SAAS,eAAe,6BAA6B;AAKrD,IAAI;AACJ,IAAI,wBAAwB;AAMrB,MAAM,UAAU;AAAA,EACrB,YAA6B,QAA4B;AAA5B;AAAA,EAA6B;AAAA,EAE1D,MAAM,UAAU,KAAa;AAM3B,UAAM,UAAU,MAAM,OAAO,SAAS;AAEtC,UAAM,SACJ,yBAAyB,KAAK,aAAa,GAAG,IAC1C,EAAE,QAAQ,QAAQ,OAAO,KAAK,EAAE,IAChC;AAAA,MACE,QAAQ,QAAQ,OAAO,OAAO,CAAC,SAAiB;AAC9C,eAAO,IAAI,KAAK,KAAK,KAAK,KAAK,OAAO;AAAA,MACxC,CAAC;AAAA,IACH;AAEN,UAAM,aAAoB,CAAC;AAC3B,eAAW;AAAA,MACT,KAAK,aAAa,GAAG,IACjB,IAAI,eAAe;AAAA,QACjB,QAAQ,EAAE,QAAQ,SAAS;AAAA,QAC3B,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW,KAAK,OAAO;AAAA,QACvB,aAAa,KAAK,OAAO;AAAA,QACzB,WAAW;AAAA,QACX,iBAAiB,MAAM,KAAK,gBAAgB;AAAA,MAC9C,CAAC,IACD,IAAI,QAAQ,WAAW,QAAQ;AAAA,IACrC;AACA,QAAI,kBAAkB;AACpB,iBAAW;AAAA,QACT,IAAI,QAAQ,WAAW,OAAO,EAAE,QAAQ,iBAAiB,CAAC;AAAA,MAC5D;AAAA,IACF;AACA,WAAO,QAAQ,aAAa;AAAA,MAC1B;AAAA,MACA,GAAG;AAAA,MACH,mBAAmB,CAAC,IAAI,QAAQ,WAAW,QAAQ,CAAC;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,kBAAwD;AAEpE,QAAI,qBAAqB;AACzB,UAAM,mBAAmB,MAAM,sBAAsB;AAErD,WAAO,OAAO,QAAsB;AAGlC,YAAM,gBAAgB,OAAO;AAC7B,UAAI,OAAO,cAAc,GAAG,GAAG;AAC7B,YAAI,CAAC,oBAAoB;AACvB,+BAAqB;AACrB,wBAAc;AAAA,YACZ,wCAAwC,IAAI,OAAO;AAAA;AAAA,EAAO,gBAAgB;AAAA;AAAA,UAC5E;AAAA,QACF;AAAA,MACF,WAAW,KAAK;AACd,sBAAc,MAAM,wCAAwC,GAAG,EAAE;AAAA,MACnE;AAEA,UAAI,KAAK;AAGP,eAAO;AAAA,UACL,MAAM,IAAI,UAAU,KAAK,MAAM,EAAE,UAAU,cAAc,CAAC;AAAA,QAC5D;AACA,sBAAc,KAAK,8BAA8B;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aAAa,KAAc;AACjC,WAAO,KAAK,OAAO;AAAA,EACrB;AACF;AAGO,SAAS,+BAA+B,QAAkB;AAC/D,qBAAmB;AACrB;AAGO,SAAS,4BAA4B;AAC1C,0BAAwB;AAC1B;","names":[]}