@atomist/sdm-core
Version:
Atomist Software Delivery Machine - Implementation
150 lines • 6.33 kB
JavaScript
"use strict";
/*
* Copyright © 2019 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.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const redact_1 = require("@atomist/automation-client/lib/util/redact");
const sdm_1 = require("@atomist/sdm");
const _ = require("lodash");
const os = require("os");
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", automation_client_1.defaultHttpClientFactory()).create(this.rolarBaseUrl);
}
get name() {
return this.logPath.join("/");
}
get url() {
return `${this.rolarBaseUrl}/logs/${this.name}`;
}
isAvailable() {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.rolarBaseUrl}/api/logs`;
try {
yield this.httpClient.exchange(url, { method: automation_client_1.HttpMethod.Head });
return true;
}
catch (e) {
automation_client_1.logger.warn(`Rolar logger is not available at ${url}: ${e}`);
return false;
}
});
}
write(msg = "", ...args) {
const fmsg = sdm_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);
}
postLogs(isClosed) {
return __awaiter(this, void 0, void 0, function* () {
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 = yield this.httpClient.exchange(url, {
method: automation_client_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)) {
automation_client_1.logger.error(err.message);
}
else {
automation_client_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