UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

139 lines 5.43 kB
"use strict"; /* * Copyright © 2020 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.RolarProgressLog = void 0; const httpClient_1 = require("@atomist/automation-client/lib/spi/http/httpClient"); const logger_1 = require("@atomist/automation-client/lib/util/logger"); const redact_1 = require("@atomist/automation-client/lib/util/redact"); const _ = require("lodash"); const os = require("os"); const format_1 = require("../../api-helper/log/format"); function* timestampGenerator() { while (true) { yield new Date(); } } /** * Post log to Atomist Rolar service for it to persist */ class RolarProgressLog { constructor(logPath, configuration, logLevel = "info", timestamper = timestampGenerator()) { this.logPath = logPath; this.logLevel = logLevel; this.timestamper = timestamper; this.localLogs = []; this.rolarBaseUrl = _.get(configuration, "sdm.rolar.url", "https://rolar.atomist.com"); this.bufferSizeLimit = _.get(configuration, "sdm.rolar.bufferSize", 10240); this.timerInterval = _.get(configuration, "sdm.rolar.flushInterval", 2000); this.redact = _.get(configuration, "redact.log", false); if (this.timerInterval > 0) { this.timer = setInterval(() => this.flush(), this.timerInterval).unref(); } this.httpClient = _.get(configuration, "http.client.factory", httpClient_1.defaultHttpClientFactory()).create(this.rolarBaseUrl); } get name() { return this.logPath.join("/"); } get url() { return `${this.rolarBaseUrl}/logs/${this.name}`; } async isAvailable() { const url = `${this.rolarBaseUrl}/api/logs`; try { await this.httpClient.exchange(url, { method: httpClient_1.HttpMethod.Head }); return true; } catch (e) { logger_1.logger.warn(`Rolar logger is not available at ${url}: ${e}`); return false; } } write(msg = "", ...args) { const fmsg = format_1.format(msg, ...args); const line = this.redact ? redact_1.redact(fmsg) : fmsg; const now = this.timestamper.next().value; this.localLogs.push({ level: this.logLevel, message: line, timestamp: this.constructUtcTimestamp(now), timestampMillis: this.constructMillisTimestamp(now), }); const bufferSize = this.localLogs.reduce((acc, logData) => acc + logData.message.length, 0); if (bufferSize > this.bufferSizeLimit) { // tslint:disable-next-line:no-floating-promises this.flush(); } } flush() { return this.postLogs(false); } close() { if (this.timer) { clearInterval(this.timer); } return this.postLogs(true); } async postLogs(isClosed) { const postingLogs = this.localLogs; this.localLogs = []; if (isClosed === true || (!!postingLogs && postingLogs.length > 0)) { const closedRequestParam = isClosed ? "?closed=true" : ""; const url = `${this.rolarBaseUrl}/api/logs/${this.logPath.join("/")}${closedRequestParam}`; let result; try { result = await this.httpClient.exchange(url, { method: httpClient_1.HttpMethod.Post, body: { host: os.hostname(), content: postingLogs || [], }, headers: { "Content-Type": "application/json" }, retry: { retries: 0, }, options: { timeout: 2500, }, }); } catch (err) { this.localLogs = postingLogs.concat(this.localLogs); if (!/timeout.*exceeded/i.test(err.message)) { logger_1.logger.error(err.message); } else { logger_1.logger.debug("Calling rolar timed out"); } } return result; } return Promise.resolve(); } constructUtcTimestamp(d) { const now = d; const date = [now.getUTCMonth() + 1, now.getUTCDate(), now.getUTCFullYear()] .map(t => _.padStart(t.toString(), 2, "0")); const time = [now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()] .map(t => _.padStart(t.toString(), 2, "0")); return `${date.join("/")} ${time.join(":")}.${_.padStart(now.getUTCMilliseconds().toString(), 3, "0")}`; } constructMillisTimestamp(d) { return d.valueOf(); } } exports.RolarProgressLog = RolarProgressLog; //# sourceMappingURL=RolarProgressLog.js.map