UNPKG

@atomist/skill-logging

Version:
160 lines 6.03 kB
"use strict"; /* * Copyright © 2022 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createLogger = createLogger; exports.chunk = chunk; exports.instanceId = instanceId; const logging_1 = require("@google-cloud/logging"); const Queue = require("better-queue"); const metadata = require("gcp-metadata"); const os = require("os"); const util = require("util"); const middleware_1 = require("./middleware"); /** * Create an instance of Logger from the current GCF context object * @param context the context parameter passed into the GCF handler entry point * @param labels additional labels to be added to the audit log */ function createLogger(context, labels = {}, name = "skills_logging", project) { if (!context || !context.correlationId || !context.workspaceId || !context.skillId) { throw new Error(`Provided context is missing correlationId, workspaceId, skillId: ${JSON.stringify(context)}`); } const logging = new logging_1.Logging({ projectId: project, }); const log = logging.log(name); let skipGl = false; // eslint-disable-next-line @typescript-eslint/no-var-requires const Store = require("better-queue-memory"); const logQueue = new Queue({ store: new Store(), process: async (entries, cb) => { const gl = async (cb, fcb) => { if (skipGl) { fcb(); } else { // Allow to write through to the console if requested if (process.env.ATOMIST_CONSOLE_LOG) { fcb(); } try { await cb(); } catch (e) { if (e.message.startsWith("Unable to detect a Project Id in the current environment.")) { fcb(); skipGl = true; } } } }; const id = await instanceId(); const filteredEntries = entries.filter(e => e.metadata.severity !== "EXIT"); filteredEntries.forEach(e => (e.metadata.labels.instance_id = id)); await gl(() => log.write(filteredEntries), () => { filteredEntries.forEach(e => console.log(`${severityToPrefix(e.metadata.severity.toString())}${e.data}`)); }); cb(); }, concurrent: 1, batchSize: 10, }); logQueue.resume(); let closing = false; let started = false; const drained = new Promise(resolve => { logQueue.on("drain", () => { if (closing) { resolve(); } }); }); const queueLog = (msg, severity, ...parameters) => { started = true; const traceIds = (0, middleware_1.getTraceIds)(); const traceId = context.traceId || (traceIds === null || traceIds === void 0 ? void 0 : traceIds.traceId); const metadata = { labels: Object.assign(Object.assign({}, labels), { event_id: context.eventId, correlation_id: context.correlationId, workspace_id: context.workspaceId, skill_id: context.skillId, execution_id: traceIds === null || traceIds === void 0 ? void 0 : traceIds.executionId, trace_id: traceId ? traceId.split("/")[0] : undefined, host: os.hostname() === "localhost" ? undefined : os.hostname() }), resource: { type: "global", }, severity: severity.toUpperCase(), timestamp: new Date(), }; chunk(util.format(msg, ...parameters)).forEach(c => { const entry = log.entry(metadata, c); if (!c) { entry.metadata = Object.assign(Object.assign({}, entry.metadata), entry.data); entry.data = c; } logQueue.push(entry); }); }; return { debug: (msg, ...parameters) => queueLog(msg, "DEBUG", ...parameters), info: (msg, ...parameters) => queueLog(msg, "INFO", ...parameters), warn: (msg, ...parameters) => queueLog(msg, "WARNING", ...parameters), error: (msg, ...parameters) => queueLog(msg, "ERROR", ...parameters), close: async () => { if (!started) { return Promise.resolve(); } closing = true; queueLog("", "EXIT"); (0, middleware_1.clearTraceIds)(); return drained; }, }; } function severityToPrefix(severity) { switch (severity) { case "DEBUG": return "[debug] "; case "INFO": return " [info] "; case "WARNING": return " [warn] "; case "ERROR": return "[error] "; } return ""; } function chunk(s, maxBytes = 256000) { if (!s || Buffer.byteLength(s) <= maxBytes) { return [s]; } // eslint-disable-next-line @typescript-eslint/no-var-requires const chunk = require("chunk-text"); return chunk(s, maxBytes, { charLengthMask: 0 }); } let InstanceId; async function instanceId() { if (!InstanceId) { try { InstanceId = await metadata.instance("id"); } catch (e) { InstanceId = "<invalid>"; } } return InstanceId !== "<invalid>" ? InstanceId : undefined; } //# sourceMappingURL=logging.js.map