@abtnode/core 1.16.13-beta-0656f92f → 1.16.13-beta-2eb54cbc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/blocklet/manager/disk.js +62 -30
- package/lib/index.js +3 -0
- package/lib/router/helper.js +142 -53
- package/lib/states/blocklet.js +71 -30
- package/lib/states/index.js +4 -0
- package/lib/states/traffic-insight.js +25 -0
- package/lib/util/blocklet.js +47 -3
- package/lib/util/index.js +23 -0
- package/lib/util/rotator.js +3 -3
- package/package.json +19 -20
|
@@ -116,6 +116,7 @@ const {
|
|
|
116
116
|
getBlockletStatus,
|
|
117
117
|
shouldSkipComponent,
|
|
118
118
|
exceedRedemptionPeriod,
|
|
119
|
+
ensureAppPortsNotOccupied,
|
|
119
120
|
} = require('../../util/blocklet');
|
|
120
121
|
const states = require('../../states');
|
|
121
122
|
const BaseBlockletManager = require('./base');
|
|
@@ -457,40 +458,66 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
457
458
|
return { did, isInstalled: !!blocklet, isRunning };
|
|
458
459
|
}
|
|
459
460
|
|
|
460
|
-
async start(
|
|
461
|
+
async start(
|
|
462
|
+
{ did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids: inputComponentDids, atomic },
|
|
463
|
+
context
|
|
464
|
+
) {
|
|
465
|
+
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
466
|
+
|
|
467
|
+
if (atomic || !blocklet.structVersion) {
|
|
468
|
+
return this._start(
|
|
469
|
+
{ did, throwOnError, checkHealthImmediately, e2eMode, componentDids: inputComponentDids },
|
|
470
|
+
context
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const componentDids = inputComponentDids?.length ? inputComponentDids : blocklet.children.map((x) => x.meta.did);
|
|
475
|
+
|
|
476
|
+
const tasks = componentDids.map((componentDid) =>
|
|
477
|
+
this._start({ did, throwOnError, checkHealthImmediately, e2eMode, componentDids: [componentDid] }, context)
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
return Promise.any(tasks).catch((err) => {
|
|
481
|
+
throw new Error(err.errors.join(', '));
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async _start(
|
|
486
|
+
{ blocklet: inputBlocklet, did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids },
|
|
487
|
+
context
|
|
488
|
+
) {
|
|
461
489
|
logger.info('start blocklet', { did, componentDids, throwOnError, checkHealthImmediately, e2eMode });
|
|
462
490
|
// should check blocklet integrity
|
|
463
|
-
const
|
|
491
|
+
const blocklet1 = inputBlocklet || (await this.ensureBlocklet(did, { e2eMode }));
|
|
464
492
|
|
|
465
|
-
await this.checkControllerStatus(
|
|
493
|
+
await this.checkControllerStatus(blocklet1, 'start');
|
|
494
|
+
|
|
495
|
+
// validate requirement and engine
|
|
496
|
+
await validateBlocklet(blocklet1);
|
|
497
|
+
await validateBlockletChainInfo(blocklet1);
|
|
498
|
+
|
|
499
|
+
if (!hasRunnableComponent(blocklet1)) {
|
|
500
|
+
throw new Error('No runnable component found');
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// check required config
|
|
504
|
+
const missingProps = getAppMissingConfigs(blocklet1);
|
|
505
|
+
if (missingProps.length) {
|
|
506
|
+
throw new Error(
|
|
507
|
+
`Missing required configuration to start the blocklet: ${missingProps.map((x) => x.key).join(',')}`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
466
510
|
|
|
467
511
|
try {
|
|
468
512
|
// blocklet may be manually stopped durning starting
|
|
469
513
|
// so error message would not be sent if blocklet is stopped
|
|
470
514
|
// so we need update status first
|
|
471
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, { componentDids });
|
|
472
|
-
|
|
515
|
+
const doc1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, { componentDids });
|
|
516
|
+
blocklet1.status = BlockletStatus.starting;
|
|
517
|
+
this.emit(BlockletEvents.statusChange, doc1);
|
|
473
518
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
await validateBlockletChainInfo(blocklet);
|
|
477
|
-
|
|
478
|
-
if (!hasRunnableComponent(blocklet)) {
|
|
479
|
-
throw new Error('No runnable component found');
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// check required config
|
|
483
|
-
const missingProps = getAppMissingConfigs(blocklet);
|
|
484
|
-
if (missingProps.length) {
|
|
485
|
-
throw new Error(
|
|
486
|
-
`Missing required configuration to start the blocklet: ${missingProps.map((x) => x.key).join(',')}`
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
this.emit(BlockletEvents.statusChange, blocklet);
|
|
491
|
-
|
|
492
|
-
if (blocklet.mode === BLOCKLET_MODES.DEVELOPMENT) {
|
|
493
|
-
const { logsDir } = blocklet.env;
|
|
519
|
+
if (blocklet1.mode === BLOCKLET_MODES.DEVELOPMENT) {
|
|
520
|
+
const { logsDir } = blocklet1.env;
|
|
494
521
|
|
|
495
522
|
try {
|
|
496
523
|
fs.removeSync(logsDir);
|
|
@@ -501,6 +528,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
501
528
|
}
|
|
502
529
|
}
|
|
503
530
|
|
|
531
|
+
const blocklet = await ensureAppPortsNotOccupied({ blocklet: blocklet1, componentDids, states, manager: this });
|
|
532
|
+
|
|
504
533
|
const getHookFn =
|
|
505
534
|
(hookName) =>
|
|
506
535
|
(b, { env }) =>
|
|
@@ -554,8 +583,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
554
583
|
}
|
|
555
584
|
|
|
556
585
|
const error = Array.isArray(err) ? err[0] : err;
|
|
557
|
-
logger.error('Failed to start blocklet', { error, did,
|
|
558
|
-
const description = `Start blocklet ${
|
|
586
|
+
logger.error('Failed to start blocklet', { error, did, title: blocklet1.meta.title });
|
|
587
|
+
const description = `Start blocklet ${blocklet1.meta.title} failed with error: ${error.message}`;
|
|
559
588
|
this._createNotification(did, {
|
|
560
589
|
title: 'Start Blocklet Failed',
|
|
561
590
|
description,
|
|
@@ -567,6 +596,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
567
596
|
await this.deleteProcess({ did, componentDids });
|
|
568
597
|
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
569
598
|
this.emit(BlockletEvents.startFailed, { ...res, error: { message: error.message } });
|
|
599
|
+
this.emit(BlockletEvents.statusChange, { ...res, error: { message: error.message } });
|
|
570
600
|
|
|
571
601
|
if (throwOnError) {
|
|
572
602
|
throw new Error(description);
|
|
@@ -583,9 +613,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
583
613
|
const { processId } = blocklet.env;
|
|
584
614
|
|
|
585
615
|
if (updateStatus) {
|
|
586
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
616
|
+
const doc = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
587
617
|
blocklet.status = BlockletStatus.stopping;
|
|
588
|
-
this.emit(BlockletEvents.statusChange,
|
|
618
|
+
this.emit(BlockletEvents.statusChange, doc);
|
|
589
619
|
}
|
|
590
620
|
|
|
591
621
|
try {
|
|
@@ -1992,6 +2022,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1992
2022
|
components: getComponentsInternalInfo(res),
|
|
1993
2023
|
});
|
|
1994
2024
|
|
|
2025
|
+
this.emit(BlockletEvents.statusChange, res);
|
|
1995
2026
|
this.emit(BlockletEvents.started, res);
|
|
1996
2027
|
logger.info('blocklet healthy', { did, name, time: Date.now() - startedAt });
|
|
1997
2028
|
} catch (error) {
|
|
@@ -2004,7 +2035,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2004
2035
|
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
2005
2036
|
|
|
2006
2037
|
await this.deleteProcess({ did, componentDids }, context);
|
|
2007
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
2038
|
+
const doc = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
2008
2039
|
|
|
2009
2040
|
this._createNotification(did, {
|
|
2010
2041
|
title: 'Blocklet Start Failed',
|
|
@@ -2015,6 +2046,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2015
2046
|
});
|
|
2016
2047
|
|
|
2017
2048
|
this.emit(BlockletEvents.startFailed, { meta, error });
|
|
2049
|
+
this.emit(BlockletEvents.statusChange, { ...doc, error });
|
|
2018
2050
|
|
|
2019
2051
|
if (throwOnError) {
|
|
2020
2052
|
throw error;
|
package/lib/index.js
CHANGED
|
@@ -411,6 +411,9 @@ function ABTNode(options) {
|
|
|
411
411
|
return states.auditLog.findPaginated.call(states.auditLog, params);
|
|
412
412
|
},
|
|
413
413
|
|
|
414
|
+
// Insights
|
|
415
|
+
getTrafficInsights: states.trafficInsight.findPaginated.bind(states.trafficInsight),
|
|
416
|
+
|
|
414
417
|
// Routing
|
|
415
418
|
routerManager,
|
|
416
419
|
addRoutingSite,
|
package/lib/router/helper.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const tar = require('tar');
|
|
6
6
|
const UUID = require('uuid');
|
|
7
|
+
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
7
8
|
const isUrl = require('is-url');
|
|
8
9
|
const get = require('lodash/get');
|
|
9
10
|
const cloneDeep = require('lodash/cloneDeep');
|
|
@@ -18,6 +19,7 @@ const downloadFile = require('@abtnode/util/lib/download-file');
|
|
|
18
19
|
const { updateBlockletDocument } = require('@abtnode/util/lib/did-document');
|
|
19
20
|
const getBlockletInfo = require('@blocklet/meta/lib/info');
|
|
20
21
|
const { forEachBlockletSync } = require('@blocklet/meta/lib/util');
|
|
22
|
+
const { processLogByDate } = require('@abtnode/analytics');
|
|
21
23
|
const {
|
|
22
24
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
23
25
|
DOMAIN_FOR_IP_SITE_REGEXP,
|
|
@@ -37,8 +39,10 @@ const {
|
|
|
37
39
|
WELLKNOWN_ACME_CHALLENGE_PREFIX,
|
|
38
40
|
WELLKNOWN_DID_RESOLVER_PREFIX,
|
|
39
41
|
WELLKNOWN_PING_PREFIX,
|
|
42
|
+
WELLKNOWN_ANALYTICS_PREFIX,
|
|
40
43
|
LOG_RETAIN_IN_DAYS,
|
|
41
44
|
EVENTS,
|
|
45
|
+
DEFAULT_IP_DOMAIN,
|
|
42
46
|
} = require('@abtnode/constant');
|
|
43
47
|
const {
|
|
44
48
|
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
@@ -51,8 +55,9 @@ const {
|
|
|
51
55
|
BLOCKLET_MODES,
|
|
52
56
|
} = require('@blocklet/constant');
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
const pkg = require('../../package.json');
|
|
59
|
+
// eslint-disable-next-line
|
|
60
|
+
const logger = require('@abtnode/logger')(`${pkg.name}:router:helper`);
|
|
56
61
|
const {
|
|
57
62
|
getProviderFromNodeInfo,
|
|
58
63
|
getHttpsCertInfo,
|
|
@@ -69,39 +74,79 @@ const Router = require('./index');
|
|
|
69
74
|
const states = require('../states');
|
|
70
75
|
const { getBlockletDomainGroupName, getDidFromDomainGroupName } = require('../util/router');
|
|
71
76
|
const { getBlockletKnownAs, getBlockletDidDomainList } = require('../util/blocklet');
|
|
77
|
+
const { toCamelCase } = require('../util/index');
|
|
78
|
+
const { get: getIp } = require('../util/ip');
|
|
72
79
|
|
|
73
80
|
const isServiceFeDevelopment = process.env.ABT_NODE_SERVICE_FE_PORT;
|
|
74
81
|
|
|
75
82
|
const hasRuleByPrefix = (site, value) => site.rules.find((x) => x.isProtected && get(x, 'from.pathPrefix') === value);
|
|
76
83
|
|
|
84
|
+
const pingWellknownRule = {
|
|
85
|
+
isProtected: true,
|
|
86
|
+
from: { pathPrefix: WELLKNOWN_PING_PREFIX },
|
|
87
|
+
to: {
|
|
88
|
+
type: ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
89
|
+
response: {
|
|
90
|
+
status: 200,
|
|
91
|
+
contentType: 'application/javascript',
|
|
92
|
+
body: "'pong'",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const analyticsWellknownRule = {
|
|
98
|
+
isProtected: true,
|
|
99
|
+
from: { pathPrefix: WELLKNOWN_ANALYTICS_PREFIX },
|
|
100
|
+
to: {
|
|
101
|
+
type: ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
102
|
+
response: {
|
|
103
|
+
status: 200,
|
|
104
|
+
contentType: 'text/html',
|
|
105
|
+
body: pkg.version,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
77
110
|
/**
|
|
78
111
|
* replace 888-888-888-888 with accessible ip for domain
|
|
79
112
|
*/
|
|
80
|
-
const attachRuntimeDomainAliases = async ({ sites = [], context = {}
|
|
113
|
+
const attachRuntimeDomainAliases = async ({ sites = [], context = {} }) => {
|
|
81
114
|
if (!sites) {
|
|
82
115
|
return [];
|
|
83
116
|
}
|
|
84
117
|
|
|
85
118
|
let ip;
|
|
86
119
|
const ipRegex = /\d+[-.]\d+[-.]\d+[-.]\d+/;
|
|
87
|
-
const match = ipRegex.exec(context.hostname);
|
|
120
|
+
const match = ipRegex.exec(context.hostname || '');
|
|
88
121
|
if (match) {
|
|
89
122
|
ip = match[0];
|
|
90
|
-
} else
|
|
91
|
-
const
|
|
92
|
-
const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
|
|
123
|
+
} else {
|
|
124
|
+
const nodeIp = await getAccessibleExternalNodeIp();
|
|
93
125
|
if (nodeIp) {
|
|
94
126
|
ip = nodeIp;
|
|
95
127
|
}
|
|
96
128
|
}
|
|
97
129
|
|
|
130
|
+
if (!ip) {
|
|
131
|
+
const result = await getIp();
|
|
132
|
+
if (result) {
|
|
133
|
+
ip = result.internal;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
logger.info('attachRuntimeDomainAliases', { ip });
|
|
138
|
+
|
|
98
139
|
const getDomainAliases = (site) =>
|
|
99
140
|
(site.domainAliases || []).map((domain) => {
|
|
100
141
|
if (!domain.value) {
|
|
101
142
|
return domain;
|
|
102
143
|
}
|
|
103
|
-
if (
|
|
104
|
-
|
|
144
|
+
if (ip) {
|
|
145
|
+
if (domain.value.includes(SLOT_FOR_IP_DNS_SITE)) {
|
|
146
|
+
domain.value = replaceSlotToIp(domain.value, ip);
|
|
147
|
+
} else if (domain.value === DEFAULT_IP_DOMAIN) {
|
|
148
|
+
domain.value = `${ip.split('.').join('-')}${domain.value.substring(2)}`;
|
|
149
|
+
}
|
|
105
150
|
}
|
|
106
151
|
return domain;
|
|
107
152
|
});
|
|
@@ -629,6 +674,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
629
674
|
const blockletState = states.blocklet;
|
|
630
675
|
const siteState = states.site;
|
|
631
676
|
const notification = states.notification;
|
|
677
|
+
const trafficInsight = states.trafficInsight;
|
|
632
678
|
|
|
633
679
|
// site level duplication detection
|
|
634
680
|
|
|
@@ -778,46 +824,12 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
778
824
|
to: proxyTarget,
|
|
779
825
|
};
|
|
780
826
|
|
|
781
|
-
const pingWellknownRule = {
|
|
782
|
-
isProtected: true,
|
|
783
|
-
from: { pathPrefix: WELLKNOWN_PING_PREFIX },
|
|
784
|
-
to: {
|
|
785
|
-
type: ROUTING_RULE_TYPES.DIRECT_RESPONSE,
|
|
786
|
-
response: {
|
|
787
|
-
status: 200,
|
|
788
|
-
contentType: 'application/javascript',
|
|
789
|
-
body: "'pong'",
|
|
790
|
-
},
|
|
791
|
-
port: info.port,
|
|
792
|
-
},
|
|
793
|
-
};
|
|
794
|
-
|
|
795
827
|
if (site) {
|
|
796
|
-
const didResolverRuleUpdateRes = await upsertSiteRule(
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
context
|
|
802
|
-
);
|
|
803
|
-
|
|
804
|
-
const acmeRuleUpdateRes = await upsertSiteRule(
|
|
805
|
-
{
|
|
806
|
-
site,
|
|
807
|
-
rule: acmeChallengeWellknownRule,
|
|
808
|
-
},
|
|
809
|
-
context
|
|
810
|
-
);
|
|
811
|
-
|
|
812
|
-
const pingRuleRes = await upsertSiteRule(
|
|
813
|
-
{
|
|
814
|
-
site,
|
|
815
|
-
rule: pingWellknownRule,
|
|
816
|
-
},
|
|
817
|
-
context
|
|
818
|
-
);
|
|
819
|
-
|
|
820
|
-
return didResolverRuleUpdateRes || acmeRuleUpdateRes || pingRuleRes;
|
|
828
|
+
const didResolverRuleUpdateRes = await upsertSiteRule({ site, rule: didResolverWellknownRule }, context);
|
|
829
|
+
const acmeRuleUpdateRes = await upsertSiteRule({ site, rule: acmeChallengeWellknownRule }, context);
|
|
830
|
+
const pingRuleRes = await upsertSiteRule({ site, rule: pingWellknownRule }, context);
|
|
831
|
+
const analyticsRuleRes = await upsertSiteRule({ site, rule: analyticsWellknownRule }, context);
|
|
832
|
+
return didResolverRuleUpdateRes || acmeRuleUpdateRes || pingRuleRes || analyticsRuleRes;
|
|
821
833
|
}
|
|
822
834
|
|
|
823
835
|
await routerManager.addRoutingSite(
|
|
@@ -826,7 +838,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
826
838
|
domain: DOMAIN_FOR_INTERNAL_SITE,
|
|
827
839
|
port: await getWellknownSitePort(),
|
|
828
840
|
name: NAME_FOR_WELLKNOWN_SITE,
|
|
829
|
-
rules: [didResolverWellknownRule, acmeChallengeWellknownRule, pingWellknownRule],
|
|
841
|
+
rules: [didResolverWellknownRule, acmeChallengeWellknownRule, pingWellknownRule, analyticsWellknownRule],
|
|
830
842
|
isProtected: true,
|
|
831
843
|
},
|
|
832
844
|
skipCheckDynamicBlacklist: true,
|
|
@@ -893,13 +905,19 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
893
905
|
|
|
894
906
|
try {
|
|
895
907
|
const result = await siteState.update({ id: dashboardSite.id }, { $set: { domainAliases } });
|
|
896
|
-
|
|
897
908
|
updatedResult.push(result);
|
|
898
909
|
} catch (error) {
|
|
899
910
|
logger.error('add dashboard domain rule failed', { error });
|
|
900
911
|
console.error('Add dashboard domain rule failed:', error);
|
|
901
912
|
}
|
|
902
913
|
|
|
914
|
+
try {
|
|
915
|
+
const result = await upsertSiteRule({ site: dashboardSite, rule: analyticsWellknownRule }, context);
|
|
916
|
+
updatedResult.push(result);
|
|
917
|
+
} catch (error) {
|
|
918
|
+
logger.error('add dashboard analytics rule failed', { error });
|
|
919
|
+
}
|
|
920
|
+
|
|
903
921
|
const defaultRule = sites.find((x) => x.domain === DOMAIN_FOR_DEFAULT_SITE);
|
|
904
922
|
if (!defaultRule) {
|
|
905
923
|
try {
|
|
@@ -1265,6 +1283,73 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1265
1283
|
}
|
|
1266
1284
|
};
|
|
1267
1285
|
|
|
1286
|
+
const analyzeRouterLog = async () => {
|
|
1287
|
+
const info = await nodeState.read();
|
|
1288
|
+
const sites = await getRoutingSites({});
|
|
1289
|
+
const providerName = get(info, 'routing.provider', null);
|
|
1290
|
+
if (!providerName || !providers[providerName]) {
|
|
1291
|
+
logger.warn('No router provider instance found');
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
const groups = [];
|
|
1296
|
+
const server = sites.find((x) =>
|
|
1297
|
+
x.rules.some((rule) => rule.to.type === ROUTING_RULE_TYPES.DAEMON && rule.to.did === info.did)
|
|
1298
|
+
);
|
|
1299
|
+
if (server) {
|
|
1300
|
+
groups.push({
|
|
1301
|
+
did: info.did,
|
|
1302
|
+
type: 'server',
|
|
1303
|
+
hosts: server.domainAliases.map((d) => d.value).filter(Boolean),
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// blocklets
|
|
1308
|
+
sites
|
|
1309
|
+
.filter((x) => x.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX))
|
|
1310
|
+
.forEach((site) => {
|
|
1311
|
+
groups.push({
|
|
1312
|
+
did: site.domain.replace(BLOCKLET_SITE_GROUP_SUFFIX, ''),
|
|
1313
|
+
type: 'blocklet',
|
|
1314
|
+
hosts: site.domainAliases.map((d) => d.value).filter(Boolean),
|
|
1315
|
+
});
|
|
1316
|
+
});
|
|
1317
|
+
logger.info('Prepare analyze router logs', groups);
|
|
1318
|
+
|
|
1319
|
+
const logDir = providers[providerName].getLogDir();
|
|
1320
|
+
const doAnalyze = async (date, groupsRaw) => {
|
|
1321
|
+
logger.info('Start analyze router logs', { date });
|
|
1322
|
+
try {
|
|
1323
|
+
let results = await processLogByDate(logDir, dataDirs.tmp, dataDirs.data, date, groupsRaw);
|
|
1324
|
+
logger.info('Done analyze router logs', { date, results });
|
|
1325
|
+
|
|
1326
|
+
results = await Promise.all(
|
|
1327
|
+
results
|
|
1328
|
+
.filter((x) => x.result)
|
|
1329
|
+
.map((x) => ({ did: x.did, date, ...toCamelCase(x.result) }))
|
|
1330
|
+
.map((x) => trafficInsight.upsert({ did: x.did, date: x.date }, x))
|
|
1331
|
+
);
|
|
1332
|
+
logger.info('Done insert insight results', { date, results });
|
|
1333
|
+
} catch (err) {
|
|
1334
|
+
logger.error('Failed to analyze router logs', { date, error: err });
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
const analyzeLock = path.join(logDir, '.analyze.lock');
|
|
1339
|
+
if (fs.existsSync(analyzeLock)) {
|
|
1340
|
+
// FIXME: @wangshijun how do we support real time logs
|
|
1341
|
+
const date = dayjs().subtract(1, 'day').format('YYYY-MM-DD');
|
|
1342
|
+
await doAnalyze(date, cloneDeep(groups));
|
|
1343
|
+
} else {
|
|
1344
|
+
fs.writeFileSync(analyzeLock, '1');
|
|
1345
|
+
for (let i = 1; i <= 30; i++) {
|
|
1346
|
+
const date = dayjs().subtract(i, 'day').format('YYYY-MM-DD');
|
|
1347
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1348
|
+
await doAnalyze(date, cloneDeep(groups));
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1268
1353
|
const updateNodeRouting = async (params, context = {}) => {
|
|
1269
1354
|
const info = await nodeState.read();
|
|
1270
1355
|
const { snapshotHash: oldSnapshotHash } = info.routing || {};
|
|
@@ -1396,7 +1481,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1396
1481
|
return attachRuntimeDomainAliases({
|
|
1397
1482
|
sites: await ensureLatestInfo(sites, { withDefaultCors }),
|
|
1398
1483
|
context,
|
|
1399
|
-
node: nodeState,
|
|
1400
1484
|
});
|
|
1401
1485
|
};
|
|
1402
1486
|
|
|
@@ -1405,7 +1489,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1405
1489
|
return attachRuntimeDomainAliases({
|
|
1406
1490
|
sites: await ensureLatestInfo(sites, { withDefaultCors }),
|
|
1407
1491
|
context,
|
|
1408
|
-
node: nodeState,
|
|
1409
1492
|
});
|
|
1410
1493
|
};
|
|
1411
1494
|
|
|
@@ -1490,7 +1573,13 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1490
1573
|
name: 'rotate-log-files',
|
|
1491
1574
|
time: '1 0 0 * * *', // rotate at 00:00:01 every day
|
|
1492
1575
|
fn: rotateRouterLog,
|
|
1493
|
-
options: { runOnInit:
|
|
1576
|
+
options: { runOnInit: process.env.ABT_NODE_JOB_NAME === 'rotate-log-files' },
|
|
1577
|
+
},
|
|
1578
|
+
{
|
|
1579
|
+
name: 'analyze-log-files',
|
|
1580
|
+
time: '0 5 0 * * *', // analyze at 00:05:00 every day
|
|
1581
|
+
fn: analyzeRouterLog,
|
|
1582
|
+
options: { runOnInit: process.env.ABT_NODE_JOB_NAME === 'analyze-log-files' },
|
|
1494
1583
|
},
|
|
1495
1584
|
],
|
|
1496
1585
|
|
package/lib/states/blocklet.js
CHANGED
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
getDisplayName,
|
|
15
15
|
forEachBlocklet,
|
|
16
16
|
forEachBlockletSync,
|
|
17
|
+
forEachComponentV2,
|
|
17
18
|
forEachComponentV2Sync,
|
|
18
19
|
getBlockletServices,
|
|
19
20
|
} = require('@blocklet/meta/lib/util');
|
|
@@ -24,6 +25,7 @@ const {
|
|
|
24
25
|
BLOCKLET_DEFAULT_PORT_NAME,
|
|
25
26
|
BlockletGroup,
|
|
26
27
|
} = require('@blocklet/constant');
|
|
28
|
+
const { refreshPorts } = require('@abtnode/util/lib/port');
|
|
27
29
|
const { APP_STRUCT_VERSION } = require('@abtnode/constant');
|
|
28
30
|
|
|
29
31
|
const logger = require('@abtnode/logger')('@abtnode/core:states:blocklet');
|
|
@@ -343,6 +345,9 @@ class BlockletState extends BaseState {
|
|
|
343
345
|
}
|
|
344
346
|
}
|
|
345
347
|
|
|
348
|
+
/**
|
|
349
|
+
* assign ports for blocklet during install/upgrade workflow
|
|
350
|
+
*/
|
|
346
351
|
async getBlockletPorts({
|
|
347
352
|
interfaces = [],
|
|
348
353
|
alreadyAssigned = {},
|
|
@@ -351,32 +356,7 @@ class BlockletState extends BaseState {
|
|
|
351
356
|
defaultPort = 0,
|
|
352
357
|
} = {}) {
|
|
353
358
|
try {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
const occupiedExternalPorts = new Map();
|
|
357
|
-
const occupiedInternalPorts = new Map();
|
|
358
|
-
|
|
359
|
-
const calcPortsFromBlocklet = (blocklet) => {
|
|
360
|
-
occupiedInternalPorts.set(Number(blocklet.port), true);
|
|
361
|
-
|
|
362
|
-
if (blocklet.ports && typeof blocklet.ports === 'object') {
|
|
363
|
-
Object.keys(blocklet.ports).forEach((key) => {
|
|
364
|
-
occupiedInternalPorts.set(Number(blocklet.ports[key]), true);
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (Array.isArray(blocklet.meta.interfaces)) {
|
|
369
|
-
blocklet.meta.interfaces.forEach((x) => {
|
|
370
|
-
if (x.port && x.port.external) {
|
|
371
|
-
occupiedExternalPorts.set(Number(x.port.external), true);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
for (const blocklet of blocklets) {
|
|
378
|
-
await forEachBlocklet(blocklet, calcPortsFromBlocklet);
|
|
379
|
-
}
|
|
359
|
+
const { occupiedExternalPorts, occupiedInternalPorts } = await this._getOccupiedPorts();
|
|
380
360
|
|
|
381
361
|
const wantedPorts = uniq(
|
|
382
362
|
interfaces
|
|
@@ -437,6 +417,30 @@ class BlockletState extends BaseState {
|
|
|
437
417
|
}
|
|
438
418
|
}
|
|
439
419
|
|
|
420
|
+
/**
|
|
421
|
+
* refresh ports for blocklet if occupied during starting workflow
|
|
422
|
+
*/
|
|
423
|
+
async refreshBlockletPorts(did, componentDids = []) {
|
|
424
|
+
const blocklet = await this.getBlocklet(did);
|
|
425
|
+
if (!blocklet) {
|
|
426
|
+
throw new Error('Blocklet does not exist');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const { occupiedExternalPorts, occupiedInternalPorts } = await this._getOccupiedPorts();
|
|
430
|
+
|
|
431
|
+
await forEachComponentV2(blocklet, async (component) => {
|
|
432
|
+
if (!shouldSkipComponent(component.meta.did, componentDids)) {
|
|
433
|
+
component.ports = await refreshPorts(component.ports, {
|
|
434
|
+
blackList: [...occupiedExternalPorts.keys(), ...occupiedInternalPorts.keys()],
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
return this.updateBlocklet(did, {
|
|
440
|
+
children: blocklet.children,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
440
444
|
async getServices() {
|
|
441
445
|
const blocklets = await this.getBlocklets({}, { meta: 1, children: 1, ports: 1 });
|
|
442
446
|
const services = [];
|
|
@@ -515,12 +519,16 @@ class BlockletState extends BaseState {
|
|
|
515
519
|
const doc = await this.getBlocklet(did);
|
|
516
520
|
|
|
517
521
|
if (doc.meta?.group === BlockletGroup.gateway && !doc.children?.length) {
|
|
518
|
-
|
|
522
|
+
const res = await this.updateBlocklet(did, { status });
|
|
523
|
+
statusLock.release();
|
|
524
|
+
return res;
|
|
519
525
|
}
|
|
520
526
|
|
|
521
527
|
// for backward compatibility
|
|
522
528
|
if (!doc.structVersion && !doc.children?.length) {
|
|
523
|
-
|
|
529
|
+
const res = await this.updateBlocklet(did, { status });
|
|
530
|
+
statusLock.release();
|
|
531
|
+
return res;
|
|
524
532
|
}
|
|
525
533
|
|
|
526
534
|
// update children status
|
|
@@ -657,10 +665,43 @@ class BlockletState extends BaseState {
|
|
|
657
665
|
|
|
658
666
|
_getStatusLock(did) {
|
|
659
667
|
if (!this.statusLocks.has(did)) {
|
|
660
|
-
this.statusLocks
|
|
668
|
+
this.statusLocks.set(did, new Lock());
|
|
661
669
|
}
|
|
662
670
|
|
|
663
|
-
return this.statusLocks
|
|
671
|
+
return this.statusLocks.get(did);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
async _getOccupiedPorts() {
|
|
675
|
+
const blocklets = await this.getBlocklets({}, { port: 1, ports: 1, meta: 1, children: 1 });
|
|
676
|
+
|
|
677
|
+
const occupiedExternalPorts = new Map();
|
|
678
|
+
const occupiedInternalPorts = new Map();
|
|
679
|
+
|
|
680
|
+
const calcPortsFromBlocklet = (blocklet) => {
|
|
681
|
+
occupiedInternalPorts.set(Number(blocklet.port), true);
|
|
682
|
+
|
|
683
|
+
if (blocklet.ports && typeof blocklet.ports === 'object') {
|
|
684
|
+
Object.keys(blocklet.ports).forEach((key) => {
|
|
685
|
+
occupiedInternalPorts.set(Number(blocklet.ports[key]), true);
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (Array.isArray(blocklet.meta.interfaces)) {
|
|
690
|
+
blocklet.meta.interfaces.forEach((x) => {
|
|
691
|
+
if (x.port && x.port.external) {
|
|
692
|
+
occupiedExternalPorts.set(Number(x.port.external), true);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
for (const blocklet of blocklets) {
|
|
699
|
+
await forEachBlocklet(blocklet, calcPortsFromBlocklet);
|
|
700
|
+
}
|
|
701
|
+
return {
|
|
702
|
+
occupiedExternalPorts,
|
|
703
|
+
occupiedInternalPorts,
|
|
704
|
+
};
|
|
664
705
|
}
|
|
665
706
|
}
|
|
666
707
|
|
package/lib/states/index.js
CHANGED
|
@@ -15,6 +15,8 @@ const CacheState = require('./cache');
|
|
|
15
15
|
const AuditLogState = require('./audit-log');
|
|
16
16
|
const JobState = require('./job');
|
|
17
17
|
const BackupState = require('./backup');
|
|
18
|
+
const TrafficInsightState = require('./traffic-insight');
|
|
19
|
+
|
|
18
20
|
const { getDbFilePath } = require('../util');
|
|
19
21
|
|
|
20
22
|
const models = getServerModels();
|
|
@@ -38,6 +40,7 @@ const init = (dataDirs, config = {}) => {
|
|
|
38
40
|
const auditLogState = new AuditLogState(models.AuditLog, config);
|
|
39
41
|
const jobState = new JobState(models.Job, config);
|
|
40
42
|
const backupState = new BackupState(models.Backup, config);
|
|
43
|
+
const trafficInsight = new TrafficInsightState(models.TrafficInsight, config);
|
|
41
44
|
|
|
42
45
|
return {
|
|
43
46
|
node: nodeState,
|
|
@@ -53,6 +56,7 @@ const init = (dataDirs, config = {}) => {
|
|
|
53
56
|
auditLog: auditLogState,
|
|
54
57
|
job: jobState,
|
|
55
58
|
backup: backupState,
|
|
59
|
+
trafficInsight,
|
|
56
60
|
};
|
|
57
61
|
};
|
|
58
62
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { Op } = require('sequelize');
|
|
2
|
+
const BaseState = require('./base');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @extends BaseState<import('@abtnode/models').TrafficInsightState>
|
|
6
|
+
*/
|
|
7
|
+
class TrafficInsight extends BaseState {
|
|
8
|
+
findPaginated({ did = '', startDate = '', endDate = '', paging = { pageSize: 30 } } = {}) {
|
|
9
|
+
const where = {};
|
|
10
|
+
if (did) {
|
|
11
|
+
where.did = did;
|
|
12
|
+
}
|
|
13
|
+
if (startDate) {
|
|
14
|
+
where.date = { [Op.gte]: startDate };
|
|
15
|
+
}
|
|
16
|
+
if (endDate) {
|
|
17
|
+
where.date = where.date || {};
|
|
18
|
+
where.date[Op.lte] = endDate;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return super.paginate({ where }, { date: -1 }, paging);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = TrafficInsight;
|
package/lib/util/blocklet.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const dayjs = require('dayjs');
|
|
5
|
+
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
6
6
|
const shelljs = require('shelljs');
|
|
7
7
|
const os = require('os');
|
|
8
8
|
const tar = require('tar');
|
|
@@ -26,7 +26,6 @@ const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
|
26
26
|
const pm2 = require('@abtnode/util/lib/async-pm2');
|
|
27
27
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
28
28
|
const getPm2ProcessInfo = require('@abtnode/util/lib/get-pm2-process-info');
|
|
29
|
-
const killProcessOccupiedPorts = require('@abtnode/util/lib/kill-process-occupied-ports');
|
|
30
29
|
const { formatEnv } = require('@abtnode/util/lib/security');
|
|
31
30
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
32
31
|
const CustomError = require('@abtnode/util/lib/custom-error');
|
|
@@ -49,6 +48,7 @@ const {
|
|
|
49
48
|
getComponentConfig,
|
|
50
49
|
} = require('@blocklet/resolver');
|
|
51
50
|
const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
|
|
51
|
+
const { isPortsOccupiedByOtherProcess, killProcessOccupiedPorts } = require('@abtnode/util/lib/port');
|
|
52
52
|
const { toSvg: createDidLogo } =
|
|
53
53
|
process.env.NODE_ENV !== 'test' ? require('@arcblock/did-motif') : require('@arcblock/did-motif/dist/did-motif.cjs');
|
|
54
54
|
const { createBlockiesSvg } = require('@blocklet/meta/lib/blockies');
|
|
@@ -80,6 +80,7 @@ const {
|
|
|
80
80
|
findWebInterface,
|
|
81
81
|
forEachBlockletSync,
|
|
82
82
|
forEachChildSync,
|
|
83
|
+
forEachComponentV2,
|
|
83
84
|
forEachComponentV2Sync,
|
|
84
85
|
getSharedConfigObj,
|
|
85
86
|
getComponentName,
|
|
@@ -569,7 +570,7 @@ const startBlockletProcess = async (
|
|
|
569
570
|
};
|
|
570
571
|
|
|
571
572
|
const clusterMode = get(b.meta, 'capabilities.clusterMode', false);
|
|
572
|
-
if (clusterMode &&
|
|
573
|
+
if (clusterMode && b.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
573
574
|
const clusterSize = Number(blocklet.configObj.BLOCKLET_CLUSTER_SIZE) || +process.env.ABT_NODE_MAX_CLUSTER_SIZE;
|
|
574
575
|
options.execMode = 'cluster';
|
|
575
576
|
options.mergeLogs = true;
|
|
@@ -1768,6 +1769,48 @@ const exceedRedemptionPeriod = (expirationDate) => {
|
|
|
1768
1769
|
return dayjs().diff(dayjs(expirationDate), 'day') > EXPIRED_BLOCKLET_DATA_RETENTION_DAYS;
|
|
1769
1770
|
};
|
|
1770
1771
|
|
|
1772
|
+
const ensureAppPortsNotOccupied = async ({
|
|
1773
|
+
blocklet,
|
|
1774
|
+
componentDids: inputDids,
|
|
1775
|
+
states,
|
|
1776
|
+
manager,
|
|
1777
|
+
checkPortsFn = isPortsOccupiedByOtherProcess,
|
|
1778
|
+
}) => {
|
|
1779
|
+
const { did } = blocklet.meta;
|
|
1780
|
+
const componentDids = [];
|
|
1781
|
+
await forEachComponentV2(blocklet, async (b) => {
|
|
1782
|
+
try {
|
|
1783
|
+
if (shouldSkipComponent(b.meta.did, inputDids)) {
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
const { processId } = b.env;
|
|
1788
|
+
const { ports } = b;
|
|
1789
|
+
if (
|
|
1790
|
+
await checkPortsFn({
|
|
1791
|
+
ports,
|
|
1792
|
+
pm2ProcessId: processId,
|
|
1793
|
+
printError: logger.error.bind(logger),
|
|
1794
|
+
})
|
|
1795
|
+
) {
|
|
1796
|
+
componentDids.push(b.meta.did);
|
|
1797
|
+
}
|
|
1798
|
+
} catch (error) {
|
|
1799
|
+
logger.error('Failed to check ports occupied', { error });
|
|
1800
|
+
}
|
|
1801
|
+
});
|
|
1802
|
+
|
|
1803
|
+
let newBlocklet = blocklet;
|
|
1804
|
+
if (componentDids.length) {
|
|
1805
|
+
await states.blocklet.refreshBlockletPorts(did, componentDids);
|
|
1806
|
+
logger.info('refresh component ports', { did, componentDids });
|
|
1807
|
+
await manager._updateBlockletEnvironment(did);
|
|
1808
|
+
newBlocklet = await manager.ensureBlocklet(did);
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
return newBlocklet;
|
|
1812
|
+
};
|
|
1813
|
+
|
|
1771
1814
|
module.exports = {
|
|
1772
1815
|
updateBlockletFallbackLogo,
|
|
1773
1816
|
forEachBlocklet,
|
|
@@ -1829,4 +1872,5 @@ module.exports = {
|
|
|
1829
1872
|
shouldSkipComponent,
|
|
1830
1873
|
getBlockletURLForLauncher,
|
|
1831
1874
|
exceedRedemptionPeriod,
|
|
1875
|
+
ensureAppPortsNotOccupied,
|
|
1832
1876
|
};
|
package/lib/util/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const dns = require('dns');
|
|
5
5
|
const crypto = require('crypto');
|
|
6
6
|
const shell = require('shelljs');
|
|
7
|
+
const camelCase = require('lodash/camelCase');
|
|
7
8
|
const get = require('lodash/get');
|
|
8
9
|
const pickBy = require('lodash/pickBy');
|
|
9
10
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
@@ -469,6 +470,27 @@ const isServerSite = (domain) =>
|
|
|
469
470
|
|
|
470
471
|
const getDbFilePath = (filePath) => (process.env.NODE_ENV === 'test' ? `${filePath}:memory:` : filePath);
|
|
471
472
|
|
|
473
|
+
const toCamelCase = (obj) => {
|
|
474
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
475
|
+
return obj;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (Array.isArray(obj)) {
|
|
479
|
+
return obj.map(toCamelCase);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
const converted = {};
|
|
483
|
+
|
|
484
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
485
|
+
for (const key in obj) {
|
|
486
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
487
|
+
converted[camelCase(key)] = toCamelCase(obj[key]);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return converted;
|
|
492
|
+
};
|
|
493
|
+
|
|
472
494
|
const lib = {
|
|
473
495
|
validateOwner,
|
|
474
496
|
getProviderFromNodeInfo,
|
|
@@ -505,6 +527,7 @@ const lib = {
|
|
|
505
527
|
isBlockletSite,
|
|
506
528
|
isServerSite,
|
|
507
529
|
getDbFilePath,
|
|
530
|
+
toCamelCase,
|
|
508
531
|
};
|
|
509
532
|
|
|
510
533
|
module.exports = lib;
|
package/lib/util/rotator.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const fs = require('fs-extra');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const
|
|
6
|
+
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
7
7
|
const zlib = require('zlib');
|
|
8
8
|
const log = require('@abtnode/logger');
|
|
9
9
|
|
|
@@ -70,11 +70,11 @@ module.exports = class LogRotate {
|
|
|
70
70
|
*/
|
|
71
71
|
proceed(file, callback = () => {}) {
|
|
72
72
|
// set default final time
|
|
73
|
-
let finalTime =
|
|
73
|
+
let finalTime = dayjs().subtract(1, 'day').format(this.dateFormat);
|
|
74
74
|
// check for a timezone
|
|
75
75
|
if (this.tz) {
|
|
76
76
|
try {
|
|
77
|
-
finalTime =
|
|
77
|
+
finalTime = dayjs().tz(this.tz).subtract(1, 'day').format(this.dateFormat);
|
|
78
78
|
} catch (err) {
|
|
79
79
|
// use default
|
|
80
80
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.13-beta-
|
|
6
|
+
"version": "1.16.13-beta-2eb54cbc",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,18 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/
|
|
23
|
-
"@abtnode/
|
|
24
|
-
"@abtnode/
|
|
25
|
-
"@abtnode/
|
|
26
|
-
"@abtnode/
|
|
27
|
-
"@abtnode/
|
|
28
|
-
"@abtnode/
|
|
29
|
-
"@abtnode/
|
|
30
|
-
"@abtnode/
|
|
31
|
-
"@abtnode/
|
|
32
|
-
"@abtnode/
|
|
33
|
-
"@abtnode/
|
|
22
|
+
"@abtnode/analytics": "1.16.13-beta-2eb54cbc",
|
|
23
|
+
"@abtnode/auth": "1.16.13-beta-2eb54cbc",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.13-beta-2eb54cbc",
|
|
25
|
+
"@abtnode/constant": "1.16.13-beta-2eb54cbc",
|
|
26
|
+
"@abtnode/cron": "1.16.13-beta-2eb54cbc",
|
|
27
|
+
"@abtnode/logger": "1.16.13-beta-2eb54cbc",
|
|
28
|
+
"@abtnode/models": "1.16.13-beta-2eb54cbc",
|
|
29
|
+
"@abtnode/queue": "1.16.13-beta-2eb54cbc",
|
|
30
|
+
"@abtnode/rbac": "1.16.13-beta-2eb54cbc",
|
|
31
|
+
"@abtnode/router-provider": "1.16.13-beta-2eb54cbc",
|
|
32
|
+
"@abtnode/static-server": "1.16.13-beta-2eb54cbc",
|
|
33
|
+
"@abtnode/timemachine": "1.16.13-beta-2eb54cbc",
|
|
34
|
+
"@abtnode/util": "1.16.13-beta-2eb54cbc",
|
|
34
35
|
"@arcblock/did": "1.18.84",
|
|
35
36
|
"@arcblock/did-auth": "1.18.84",
|
|
36
37
|
"@arcblock/did-ext": "^1.18.84",
|
|
@@ -41,10 +42,10 @@
|
|
|
41
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
42
43
|
"@arcblock/validator": "^1.18.84",
|
|
43
44
|
"@arcblock/vc": "1.18.84",
|
|
44
|
-
"@blocklet/constant": "1.16.13-beta-
|
|
45
|
-
"@blocklet/meta": "1.16.13-beta-
|
|
46
|
-
"@blocklet/resolver": "1.16.13-beta-
|
|
47
|
-
"@blocklet/sdk": "1.16.13-beta-
|
|
45
|
+
"@blocklet/constant": "1.16.13-beta-2eb54cbc",
|
|
46
|
+
"@blocklet/meta": "1.16.13-beta-2eb54cbc",
|
|
47
|
+
"@blocklet/resolver": "1.16.13-beta-2eb54cbc",
|
|
48
|
+
"@blocklet/sdk": "1.16.13-beta-2eb54cbc",
|
|
48
49
|
"@did-space/client": "^0.2.117",
|
|
49
50
|
"@fidm/x509": "^1.2.1",
|
|
50
51
|
"@ocap/mcrypto": "1.18.84",
|
|
@@ -56,7 +57,6 @@
|
|
|
56
57
|
"axon": "^2.0.3",
|
|
57
58
|
"chalk": "^4.1.2",
|
|
58
59
|
"cross-spawn": "^7.0.3",
|
|
59
|
-
"dayjs": "^1.11.7",
|
|
60
60
|
"deep-diff": "^1.0.2",
|
|
61
61
|
"detect-port": "^1.5.1",
|
|
62
62
|
"escape-string-regexp": "^4.0.0",
|
|
@@ -73,7 +73,6 @@
|
|
|
73
73
|
"kill-port": "^2.0.1",
|
|
74
74
|
"lodash": "^4.17.21",
|
|
75
75
|
"lru-cache": "^6.0.0",
|
|
76
|
-
"moment-timezone": "^0.5.37",
|
|
77
76
|
"node-stream-zip": "^1.15.0",
|
|
78
77
|
"p-limit": "^3.1.0",
|
|
79
78
|
"p-retry": "4.6.1",
|
|
@@ -97,5 +96,5 @@
|
|
|
97
96
|
"express": "^4.18.2",
|
|
98
97
|
"jest": "^27.5.1"
|
|
99
98
|
},
|
|
100
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "7adf96c2eb31762d8eb14b8121fce9865d6a458c"
|
|
101
100
|
}
|