Skip to content

Commit 405c96b

Browse files
committed
feat(logs): support addon logs
1 parent 17b81b7 commit 405c96b

File tree

6 files changed

+261
-53
lines changed

6 files changed

+261
-53
lines changed

package-lock.json

Lines changed: 57 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"scripts/*.sh"
2727
],
2828
"dependencies": {
29-
"@clevercloud/client": "9.2.0",
29+
"@clevercloud/client": "file:../clever-client.js",
3030
"@inquirer/prompts": "7.3.2",
3131
"cliparse": "0.5.0",
3232
"colors": "1.4.0",

src/commands/logs.js

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as Log from '../models/log-v4.js';
44
import { Logger } from '../logger.js';
55
import { Deferred } from '../models/utils.js';
66
import colors from 'colors/safe.js';
7-
import { resolveAddonId } from '../models/ids-resolver.js';
7+
import { resolveAddonId, resolveRealId, resolveOwnerId } from '../models/ids-resolver.js';
88

99
export async function appLogs (params) {
1010
const { alias, app: appIdOrName, addon: addonIdOrRealId, after: since, before: until, search, 'deployment-id': deploymentId, format } = params.options;
@@ -13,18 +13,14 @@ export async function appLogs (params) {
1313
const filter = (search !== '') ? search : null;
1414
const isForHuman = (format === 'human');
1515

16-
// TODO: drop when addons are migrated to the v4 API
1716
if (addonIdOrRealId != null) {
18-
const addonId = await resolveAddonId(addonIdOrRealId);
19-
if (isForHuman) {
20-
Logger.println(colors.blue('Waiting for addon logs…'));
21-
}
22-
else {
23-
throw new Error(`"${format}" format is not yet available for add-on logs`);
24-
}
25-
return LogV2.displayLogs({ appAddonId: addonId, since, until, filter, deploymentId });
17+
return addonLogs({addonIdOrRealId, isForHuman, since, until, filter, format, since, until, deploymentId, format, filter});
2618
}
2719

20+
applicationLogs({appIdOrName, alias, isForHuman})
21+
}
22+
23+
async function applicationLogs({appIdOrName, alias, isForHuman, since, until, deploymentId, format, filter}) {
2824
const { ownerId, appId } = await Application.resolveId(appIdOrName, alias);
2925

3026
if (isForHuman) {
@@ -35,3 +31,22 @@ export async function appLogs (params) {
3531
await Log.displayLogs({ ownerId, appId, since, until, filter, deploymentId, format, deferred });
3632
return deferred.promise;
3733
}
34+
35+
async function addonLogs({addonIdOrRealId, isForHuman, since, until, filter, format}) {
36+
let addonId = addonIdOrRealId
37+
if(addonId.startsWith("addon_")) {
38+
addonId = await resolveRealId(addonIdOrRealId);
39+
}
40+
41+
const ownerId = await resolveOwnerId(addonId)
42+
43+
if (isForHuman) {
44+
Logger.println(colors.blue('Waiting for addon logs…'));
45+
}
46+
47+
const deferred = new Deferred();
48+
console.log({ ownerId, addonId, since, until, filter, format, deferred })
49+
await Log.displayAddonLogs({ ownerId, addonId, since, until, filter, format, deferred });
50+
return deferred.promise;
51+
}
52+

src/models/AddonLogs.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
2+
// Wait for https://github.com/CleverCloud/clever-client.js/pull/129 to be merged
3+
const _cleverCloudSse = require('@clevercloud/client/cjs/streams/clever-cloud-sse.js');
4+
5+
const RESOURCE_LOG_EVENT_NAME = 'RESOURCE_LOG';
6+
7+
class ApplicationAddonLogStream extends _cleverCloudSse.default {
8+
/**
9+
* @param {object} options
10+
* @param {string} options.apiHost
11+
* @param {object} options.tokens
12+
* @param {string} options.tokens.OAUTH_CONSUMER_KEY
13+
* @param {string} options.tokens.OAUTH_CONSUMER_SECRET
14+
* @param {string} options.tokens.API_OAUTH_TOKEN
15+
* @param {string} options.tokens.API_OAUTH_TOKEN_SECRET
16+
* @param {string} options.ownerId
17+
* @param {string} options.addonId
18+
* @param {number} options.connectionTimeout
19+
* @param {object} options.retryConfiguration
20+
* @param {boolean} options.retryConfiguration.enabled
21+
* @param {number} options.retryConfiguration.backoffFactor
22+
* @param {number} options.retryConfiguration.initRetryTimeout
23+
* @param {number} options.retryConfiguration.maxRetryCount
24+
* @param {Date} options.since
25+
* @param {Date} options.until
26+
* @param {number} options.limit
27+
* @param {string} options.filter
28+
* @param {string} options.field[]
29+
* @param {number} options.throttleElements
30+
* @param {number} options.throttlePerInMilliseconds
31+
*/
32+
constructor({
33+
apiHost,
34+
tokens,
35+
ownerId,
36+
addonId,
37+
retryConfiguration,
38+
connectionTimeout,
39+
...options
40+
}) {
41+
super(apiHost, tokens, retryConfiguration ?? {}, connectionTimeout);
42+
this._ownerId = ownerId;
43+
this._addonId = addonId;
44+
this._options = options; // Count the number of logs, so we can update the "limit" query param on pause/resume or error/retry
45+
46+
this._logsCount = 0;
47+
this.onLog(() => {
48+
this._logsCount++;
49+
});
50+
}
51+
/**
52+
* compute full URL with query params
53+
* @returns {URL}
54+
*/
55+
56+
57+
getUrl() {
58+
return this.buildUrl(`/v4/logs/organisations/${this._ownerId}/resources/${this._addonId}/logs`, { ...this._options,
59+
// in case of pause() then resume():
60+
// we don' t want N another logs, we want the initial passed number less the events count already received
61+
limit: this._computedLimit(),
62+
service: 'all' // TODO: debug
63+
});
64+
} // compute the number of events to retrieve, based on elements already received
65+
66+
67+
_computedLimit() {
68+
if (this._options.limit == null) {
69+
return null;
70+
}
71+
72+
return Math.max(this._options.limit - this._logsCount, 0);
73+
}
74+
/**
75+
* override default method
76+
*/
77+
78+
79+
transform(event, data) {
80+
if (event !== RESOURCE_LOG_EVENT_NAME) {
81+
return data;
82+
}
83+
84+
const log = JSON.parse(data);
85+
86+
if (log.date) {
87+
log.date = new Date(log.date);
88+
}
89+
90+
return log;
91+
}
92+
/**
93+
* shortcut for .on('APPLICATION_LOG', (event) => ...)
94+
* @param {Function} fn which handle logs
95+
* @returns {any}
96+
*/
97+
98+
99+
onLog(fn) {
100+
return this.on(RESOURCE_LOG_EVENT_NAME, event => fn(event.data));
101+
}
102+
103+
}
104+
105+
module.exports = {ApplicationAddonLogStream}

src/models/ids-resolver.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export async function resolveRealId (id) {
5252
return realId;
5353
}
5454

55-
throw new Error(`Add-on ${id} does not exist foo`);
55+
throw new Error(`Add-on ${id} does not exist`);
5656
}
5757

5858
async function getIdFromCacheOrSummary (callback) {

0 commit comments

Comments
 (0)