@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
139 lines • 5.43 kB
JavaScript
"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