1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | const automation_client_1 = require("@atomist/automation-client");
|
19 | const retry_1 = require("@atomist/automation-client/util/retry");
|
20 | const axios_1 = require("axios");
|
21 | const _ = require("lodash");
|
22 | const os = require("os");
|
23 | function* timestampGenerator() {
|
24 | while (true) {
|
25 | yield new Date();
|
26 | }
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | class RolarProgressLog {
|
32 | constructor(rolarBaseUrl, logPath, bufferSizeLimit = 1000, timerInterval = 0, logLevel = "info", timestamper = timestampGenerator(), retryOptions = {}, axiosInstance = axios_1.default) {
|
33 | this.rolarBaseUrl = rolarBaseUrl;
|
34 | this.logPath = logPath;
|
35 | this.bufferSizeLimit = bufferSizeLimit;
|
36 | this.timerInterval = timerInterval;
|
37 | this.logLevel = logLevel;
|
38 | this.timestamper = timestamper;
|
39 | this.retryOptions = retryOptions;
|
40 | this.axiosInstance = axiosInstance;
|
41 | this.localLogs = [];
|
42 | if (this.timerInterval > 0) {
|
43 | this.timer = setInterval(() => this.flush(), 2000);
|
44 | }
|
45 | }
|
46 | get name() {
|
47 | return this.logPath.join("/");
|
48 | }
|
49 | get url() {
|
50 | return `${this.rolarBaseUrl}/logs/${this.name}`;
|
51 | }
|
52 | async isAvailable() {
|
53 | const url = `${this.rolarBaseUrl}/api/logs`;
|
54 | try {
|
55 | await retry_1.doWithRetry(() => this.axiosInstance.head(url), `check if Rolar service is available`, this.retryOptions);
|
56 | return true;
|
57 | }
|
58 | catch (e) {
|
59 | automation_client_1.logger.warn(`Rolar logger is NOT available at ${url}: ${e}`);
|
60 | return false;
|
61 | }
|
62 | }
|
63 | write(what) {
|
64 | const line = what || "";
|
65 | this.localLogs.push({
|
66 | level: this.logLevel,
|
67 | message: line,
|
68 | timestamp: this.constructUtcTimestamp(),
|
69 | });
|
70 | const bufferSize = this.localLogs.reduce((acc, logData) => acc + logData.message.length, 0);
|
71 | if (bufferSize > this.bufferSizeLimit) {
|
72 |
|
73 | this.flush();
|
74 | }
|
75 | }
|
76 | flush() {
|
77 | return this.postLogs(false);
|
78 | }
|
79 | close() {
|
80 | if (this.timer) {
|
81 | clearInterval(this.timer);
|
82 | }
|
83 | return this.postLogs(true);
|
84 | }
|
85 | async postLogs(isClosed) {
|
86 | const postingLogs = this.localLogs;
|
87 | this.localLogs = [];
|
88 | if (postingLogs && postingLogs.length > 0) {
|
89 | const closedRequestParam = isClosed ? "?closed=true" : "";
|
90 | const url = `${this.rolarBaseUrl}/api/logs/${this.logPath.join("/")}${closedRequestParam}`;
|
91 | const result = await retry_1.doWithRetry(() => this.axiosInstance.post(url, {
|
92 | host: os.hostname(),
|
93 | content: postingLogs,
|
94 | }, {
|
95 | headers: { "Content-Type": "application/json" },
|
96 | }).catch(axiosError => Promise.reject(new Error(`Failure post to ${url}: ${axiosError.message}`))), `post log to Rolar`, this.retryOptions).catch(e => {
|
97 | this.localLogs = postingLogs.concat(this.localLogs);
|
98 | automation_client_1.logger.error(e);
|
99 | });
|
100 | return result;
|
101 | }
|
102 | return Promise.resolve();
|
103 | }
|
104 | constructUtcTimestamp() {
|
105 | if (!this.timestamper) {
|
106 | return "";
|
107 | }
|
108 | const now = this.timestamper.next().value;
|
109 | const date = [now.getUTCMonth() + 1, now.getUTCDate(), now.getUTCFullYear()]
|
110 | .map(t => _.padStart(t.toString(), 2, "0"));
|
111 | const time = [now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()]
|
112 | .map(t => _.padStart(t.toString(), 2, "0"));
|
113 | return `${date.join("/")} ${time.join(":")}.${_.padStart(now.getUTCMilliseconds().toString(), 3, "0")}`;
|
114 | }
|
115 | }
|
116 | exports.RolarProgressLog = RolarProgressLog;
|
117 |
|
\ | No newline at end of file |