@crawlee/utils 3.13.5 → 4.0.0-beta.0
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/index.d.ts +15 -16
- package/index.d.ts.map +1 -1
- package/index.js +15 -22
- package/index.js.map +1 -1
- package/internals/blocked.js +4 -7
- package/internals/blocked.js.map +1 -1
- package/internals/cheerio.d.ts +4 -5
- package/internals/cheerio.d.ts.map +1 -1
- package/internals/cheerio.js +9 -17
- package/internals/cheerio.js.map +1 -1
- package/internals/chunk.js +1 -4
- package/internals/chunk.js.map +1 -1
- package/internals/debug.js +5 -9
- package/internals/debug.js.map +1 -1
- package/internals/extract-urls.js +17 -23
- package/internals/extract-urls.js.map +1 -1
- package/internals/general.js +19 -31
- package/internals/general.js.map +1 -1
- package/internals/memory-info.js +22 -26
- package/internals/memory-info.js.map +1 -1
- package/internals/open_graph_parser.js +3 -6
- package/internals/open_graph_parser.js.map +1 -1
- package/internals/robots.d.ts +1 -1
- package/internals/robots.d.ts.map +1 -1
- package/internals/robots.js +16 -26
- package/internals/robots.js.map +1 -1
- package/internals/sitemap.d.ts.map +1 -1
- package/internals/sitemap.js +28 -73
- package/internals/sitemap.js.map +1 -1
- package/internals/social.js +37 -46
- package/internals/social.js.map +1 -1
- package/internals/systemInfoV2/cpu-info.js +26 -36
- package/internals/systemInfoV2/cpu-info.js.map +1 -1
- package/internals/systemInfoV2/memory-info.js +22 -26
- package/internals/systemInfoV2/memory-info.js.map +1 -1
- package/internals/systemInfoV2/ps-tree.js +5 -9
- package/internals/systemInfoV2/ps-tree.js.map +1 -1
- package/internals/typedefs.js +2 -6
- package/internals/typedefs.js.map +1 -1
- package/internals/url.js +1 -4
- package/internals/url.js.map +1 -1
- package/package.json +13 -22
- package/tsconfig.build.tsbuildinfo +1 -1
- package/index.mjs +0 -36
- package/internals/gotScraping.d.ts +0 -5
- package/internals/gotScraping.d.ts.map +0 -1
- package/internals/gotScraping.js +0 -10
- package/internals/gotScraping.js.map +0 -1
package/internals/social.js
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.DISCORD_REGEX_GLOBAL = exports.DISCORD_REGEX = exports.PINTEREST_REGEX_GLOBAL = exports.PINTEREST_REGEX = exports.TIKTOK_REGEX_GLOBAL = exports.TIKTOK_REGEX = exports.YOUTUBE_REGEX_GLOBAL = exports.YOUTUBE_REGEX = exports.FACEBOOK_REGEX_GLOBAL = exports.FACEBOOK_REGEX = exports.TWITTER_REGEX_GLOBAL = exports.TWITTER_REGEX = exports.INSTAGRAM_REGEX_GLOBAL = exports.INSTAGRAM_REGEX = exports.LINKEDIN_REGEX_GLOBAL = exports.LINKEDIN_REGEX = exports.EMAIL_REGEX_GLOBAL = exports.EMAIL_REGEX = void 0;
|
|
4
|
-
exports.emailsFromText = emailsFromText;
|
|
5
|
-
exports.emailsFromUrls = emailsFromUrls;
|
|
6
|
-
exports.phonesFromText = phonesFromText;
|
|
7
|
-
exports.phonesFromUrls = phonesFromUrls;
|
|
8
|
-
exports.parseHandlesFromHtml = parseHandlesFromHtml;
|
|
9
|
-
const tslib_1 = require("tslib");
|
|
10
|
-
const cheerio = tslib_1.__importStar(require("cheerio"));
|
|
11
|
-
const cheerio_1 = require("./cheerio");
|
|
1
|
+
import * as cheerio from 'cheerio';
|
|
2
|
+
import { htmlToText } from './cheerio.js';
|
|
12
3
|
// Regex inspired by https://zapier.com/blog/extract-links-email-phone-regex/
|
|
13
4
|
const EMAIL_REGEX_STRING = '(?:[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])';
|
|
14
5
|
/**
|
|
15
6
|
* Regular expression to exactly match a single email address.
|
|
16
7
|
* It has the following form: `/^...$/i`.
|
|
17
8
|
*/
|
|
18
|
-
|
|
9
|
+
export const EMAIL_REGEX = new RegExp(`^${EMAIL_REGEX_STRING}$`, 'i');
|
|
19
10
|
/**
|
|
20
11
|
* Regular expression to find multiple email addresses in a text.
|
|
21
12
|
* It has the following form: `/.../ig`.
|
|
22
13
|
*/
|
|
23
|
-
|
|
14
|
+
export const EMAIL_REGEX_GLOBAL = new RegExp(EMAIL_REGEX_STRING, 'ig');
|
|
24
15
|
const EMAIL_URL_PREFIX_REGEX = /^mailto:/i;
|
|
25
16
|
/**
|
|
26
17
|
* The function extracts email addresses from a plain text.
|
|
@@ -29,10 +20,10 @@ const EMAIL_URL_PREFIX_REGEX = /^mailto:/i;
|
|
|
29
20
|
* @return Array of emails addresses found.
|
|
30
21
|
* If no emails are found, the function returns an empty array.
|
|
31
22
|
*/
|
|
32
|
-
function emailsFromText(text) {
|
|
23
|
+
export function emailsFromText(text) {
|
|
33
24
|
if (typeof text !== 'string')
|
|
34
25
|
return [];
|
|
35
|
-
return text.match(
|
|
26
|
+
return text.match(EMAIL_REGEX_GLOBAL) || [];
|
|
36
27
|
}
|
|
37
28
|
/**
|
|
38
29
|
* The function extracts email addresses from a list of URLs.
|
|
@@ -42,7 +33,7 @@ function emailsFromText(text) {
|
|
|
42
33
|
* @return Array of emails addresses found.
|
|
43
34
|
* If no emails are found, the function returns an empty array.
|
|
44
35
|
*/
|
|
45
|
-
function emailsFromUrls(urls) {
|
|
36
|
+
export function emailsFromUrls(urls) {
|
|
46
37
|
if (!Array.isArray(urls))
|
|
47
38
|
throw new Error('The "urls" parameter must be an array');
|
|
48
39
|
const emails = [];
|
|
@@ -52,7 +43,7 @@ function emailsFromUrls(urls) {
|
|
|
52
43
|
if (!EMAIL_URL_PREFIX_REGEX.test(url))
|
|
53
44
|
continue;
|
|
54
45
|
const email = url.replace(EMAIL_URL_PREFIX_REGEX, '').trim();
|
|
55
|
-
if (
|
|
46
|
+
if (EMAIL_REGEX.test(email))
|
|
56
47
|
emails.push(email);
|
|
57
48
|
}
|
|
58
49
|
return emails;
|
|
@@ -112,7 +103,7 @@ const SKIP_PHONE_REGEX = new RegExp(`^(${SKIP_PHONE_REGEXS.join('|')})$`, 'i');
|
|
|
112
103
|
* @return Array of phone numbers found.
|
|
113
104
|
* If no phone numbers are found, the function returns an empty array.
|
|
114
105
|
*/
|
|
115
|
-
function phonesFromText(text) {
|
|
106
|
+
export function phonesFromText(text) {
|
|
116
107
|
if (typeof text !== 'string')
|
|
117
108
|
return [];
|
|
118
109
|
let phones = text.match(PHONE_REGEX_GLOBAL) || [];
|
|
@@ -136,7 +127,7 @@ function phonesFromText(text) {
|
|
|
136
127
|
* @return Array of phone numbers found.
|
|
137
128
|
* If no phone numbers are found, the function returns an empty array.
|
|
138
129
|
*/
|
|
139
|
-
function phonesFromUrls(urls) {
|
|
130
|
+
export function phonesFromUrls(urls) {
|
|
140
131
|
if (!Array.isArray(urls))
|
|
141
132
|
throw new Error('The "urls" parameter must be an array');
|
|
142
133
|
const phones = [];
|
|
@@ -191,7 +182,7 @@ const DISCORD_REGEX_STRING = '(?<!\\w)(?:https?:\\/\\/)?(?:www\\.)?((?:(?:(?:can
|
|
|
191
182
|
* }
|
|
192
183
|
* ```
|
|
193
184
|
*/
|
|
194
|
-
|
|
185
|
+
export const LINKEDIN_REGEX = new RegExp(`^${LINKEDIN_REGEX_STRING}$`, 'i');
|
|
195
186
|
/**
|
|
196
187
|
* Regular expression to find multiple LinkedIn profile URLs in a text or HTML.
|
|
197
188
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -220,7 +211,7 @@ exports.LINKEDIN_REGEX = new RegExp(`^${LINKEDIN_REGEX_STRING}$`, 'i');
|
|
|
220
211
|
* if (matches) console.log(`${matches.length} LinkedIn profiles found!`);
|
|
221
212
|
* ```
|
|
222
213
|
*/
|
|
223
|
-
|
|
214
|
+
export const LINKEDIN_REGEX_GLOBAL = new RegExp(LINKEDIN_REGEX_STRING, 'ig');
|
|
224
215
|
/**
|
|
225
216
|
* Regular expression to exactly match a single Instagram profile URL.
|
|
226
217
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -251,7 +242,7 @@ exports.LINKEDIN_REGEX_GLOBAL = new RegExp(LINKEDIN_REGEX_STRING, 'ig');
|
|
|
251
242
|
* }
|
|
252
243
|
* ```
|
|
253
244
|
*/
|
|
254
|
-
|
|
245
|
+
export const INSTAGRAM_REGEX = new RegExp(`^${INSTAGRAM_REGEX_STRING}$`, 'i');
|
|
255
246
|
/**
|
|
256
247
|
* Regular expression to find multiple Instagram profile URLs in a text or HTML.
|
|
257
248
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -286,7 +277,7 @@ exports.INSTAGRAM_REGEX = new RegExp(`^${INSTAGRAM_REGEX_STRING}$`, 'i');
|
|
|
286
277
|
* if (matches) console.log(`${matches.length} Instagram profiles found!`);
|
|
287
278
|
* ```
|
|
288
279
|
*/
|
|
289
|
-
|
|
280
|
+
export const INSTAGRAM_REGEX_GLOBAL = new RegExp(INSTAGRAM_REGEX_STRING, 'ig');
|
|
290
281
|
/**
|
|
291
282
|
* Regular expression to exactly match a single Twitter profile URL.
|
|
292
283
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -310,7 +301,7 @@ exports.INSTAGRAM_REGEX_GLOBAL = new RegExp(INSTAGRAM_REGEX_STRING, 'ig');
|
|
|
310
301
|
* }
|
|
311
302
|
* ```
|
|
312
303
|
*/
|
|
313
|
-
|
|
304
|
+
export const TWITTER_REGEX = new RegExp(`^${TWITTER_REGEX_STRING}$`, 'i');
|
|
314
305
|
/**
|
|
315
306
|
* Regular expression to find multiple Twitter profile URLs in a text or HTML.
|
|
316
307
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -337,7 +328,7 @@ exports.TWITTER_REGEX = new RegExp(`^${TWITTER_REGEX_STRING}$`, 'i');
|
|
|
337
328
|
* if (matches) console.log(`${matches.length} Twitter profiles found!`);
|
|
338
329
|
* ```
|
|
339
330
|
*/
|
|
340
|
-
|
|
331
|
+
export const TWITTER_REGEX_GLOBAL = new RegExp(TWITTER_REGEX_STRING, 'ig');
|
|
341
332
|
/**
|
|
342
333
|
* Regular expression to exactly match a single Facebook profile URL.
|
|
343
334
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -363,7 +354,7 @@ exports.TWITTER_REGEX_GLOBAL = new RegExp(TWITTER_REGEX_STRING, 'ig');
|
|
|
363
354
|
* }
|
|
364
355
|
* ```
|
|
365
356
|
*/
|
|
366
|
-
|
|
357
|
+
export const FACEBOOK_REGEX = new RegExp(`^${FACEBOOK_REGEX_STRING}$`, 'i');
|
|
367
358
|
/**
|
|
368
359
|
* Regular expression to find multiple Facebook profile URLs in a text or HTML.
|
|
369
360
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -391,7 +382,7 @@ exports.FACEBOOK_REGEX = new RegExp(`^${FACEBOOK_REGEX_STRING}$`, 'i');
|
|
|
391
382
|
* if (matches) console.log(`${matches.length} Facebook profiles found!`);
|
|
392
383
|
* ```
|
|
393
384
|
*/
|
|
394
|
-
|
|
385
|
+
export const FACEBOOK_REGEX_GLOBAL = new RegExp(FACEBOOK_REGEX_STRING, 'ig');
|
|
395
386
|
/**
|
|
396
387
|
* Regular expression to exactly match a single Youtube channel, user or video URL.
|
|
397
388
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -414,7 +405,7 @@ exports.FACEBOOK_REGEX_GLOBAL = new RegExp(FACEBOOK_REGEX_STRING, 'ig');
|
|
|
414
405
|
* }
|
|
415
406
|
* ```
|
|
416
407
|
*/
|
|
417
|
-
|
|
408
|
+
export const YOUTUBE_REGEX = new RegExp(`^${YOUTUBE_REGEX_STRING}$`, 'i');
|
|
418
409
|
/**
|
|
419
410
|
* Regular expression to find multiple Youtube channel, user or video URLs in a text or HTML.
|
|
420
411
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -436,7 +427,7 @@ exports.YOUTUBE_REGEX = new RegExp(`^${YOUTUBE_REGEX_STRING}$`, 'i');
|
|
|
436
427
|
* if (matches) console.log(`${matches.length} Youtube videos found!`);
|
|
437
428
|
* ```
|
|
438
429
|
*/
|
|
439
|
-
|
|
430
|
+
export const YOUTUBE_REGEX_GLOBAL = new RegExp(YOUTUBE_REGEX_STRING, 'ig');
|
|
440
431
|
/**
|
|
441
432
|
* Regular expression to exactly match a Tiktok video or user account.
|
|
442
433
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -458,7 +449,7 @@ exports.YOUTUBE_REGEX_GLOBAL = new RegExp(YOUTUBE_REGEX_STRING, 'ig');
|
|
|
458
449
|
* }
|
|
459
450
|
* ```
|
|
460
451
|
*/
|
|
461
|
-
|
|
452
|
+
export const TIKTOK_REGEX = new RegExp(`^${TIKTOK_REGEX_STRING}$`, 'i');
|
|
462
453
|
/**
|
|
463
454
|
* Regular expression to find multiple Tiktok videos or user accounts in a text or HTML.
|
|
464
455
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -479,7 +470,7 @@ exports.TIKTOK_REGEX = new RegExp(`^${TIKTOK_REGEX_STRING}$`, 'i');
|
|
|
479
470
|
* if (matches) console.log(`${matches.length} Tiktok profiles/videos found!`);
|
|
480
471
|
* ```
|
|
481
472
|
*/
|
|
482
|
-
|
|
473
|
+
export const TIKTOK_REGEX_GLOBAL = new RegExp(TIKTOK_REGEX_STRING, 'ig');
|
|
483
474
|
/**
|
|
484
475
|
* Regular expression to exactly match a Pinterest pin, user or user's board.
|
|
485
476
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -502,7 +493,7 @@ exports.TIKTOK_REGEX_GLOBAL = new RegExp(TIKTOK_REGEX_STRING, 'ig');
|
|
|
502
493
|
* }
|
|
503
494
|
* ```
|
|
504
495
|
*/
|
|
505
|
-
|
|
496
|
+
export const PINTEREST_REGEX = new RegExp(`^${PINTEREST_REGEX_STRING}$`, 'i');
|
|
506
497
|
/**
|
|
507
498
|
* Regular expression to find multiple Pinterest pins, users or boards in a text or HTML.
|
|
508
499
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -524,7 +515,7 @@ exports.PINTEREST_REGEX = new RegExp(`^${PINTEREST_REGEX_STRING}$`, 'i');
|
|
|
524
515
|
* if (matches) console.log(`${matches.length} Pinterest pins found!`);
|
|
525
516
|
* ```
|
|
526
517
|
*/
|
|
527
|
-
|
|
518
|
+
export const PINTEREST_REGEX_GLOBAL = new RegExp(PINTEREST_REGEX_STRING, 'ig');
|
|
528
519
|
/**
|
|
529
520
|
* Regular expression to exactly match a Discord invite or channel.
|
|
530
521
|
* It has the following form: `/^...$/i` and matches URLs such as:
|
|
@@ -545,7 +536,7 @@ exports.PINTEREST_REGEX_GLOBAL = new RegExp(PINTEREST_REGEX_STRING, 'ig');
|
|
|
545
536
|
* }
|
|
546
537
|
* ```
|
|
547
538
|
*/
|
|
548
|
-
|
|
539
|
+
export const DISCORD_REGEX = new RegExp(`^${DISCORD_REGEX_STRING}$`, 'i');
|
|
549
540
|
/**
|
|
550
541
|
* Regular expression to find multiple Discord channels or invites in a text or HTML.
|
|
551
542
|
* It has the following form: `/.../ig` and matches URLs such as:
|
|
@@ -565,7 +556,7 @@ exports.DISCORD_REGEX = new RegExp(`^${DISCORD_REGEX_STRING}$`, 'i');
|
|
|
565
556
|
* if (matches) console.log(`${matches.length} Discord channels found!`);
|
|
566
557
|
* ```
|
|
567
558
|
*/
|
|
568
|
-
|
|
559
|
+
export const DISCORD_REGEX_GLOBAL = new RegExp(DISCORD_REGEX_STRING, 'ig');
|
|
569
560
|
/**
|
|
570
561
|
* The function attempts to extract emails, phone numbers and social profile URLs from a HTML document,
|
|
571
562
|
* specifically LinkedIn, Twitter, Instagram and Facebook profile URLs.
|
|
@@ -596,7 +587,7 @@ exports.DISCORD_REGEX_GLOBAL = new RegExp(DISCORD_REGEX_STRING, 'ig');
|
|
|
596
587
|
* so that the caller doesn't need to parse the HTML document again, if needed.
|
|
597
588
|
* @return An object with the social handles.
|
|
598
589
|
*/
|
|
599
|
-
function parseHandlesFromHtml(html, data = null) {
|
|
590
|
+
export function parseHandlesFromHtml(html, data = null) {
|
|
600
591
|
const result = {
|
|
601
592
|
emails: [],
|
|
602
593
|
phones: [],
|
|
@@ -612,10 +603,10 @@ function parseHandlesFromHtml(html, data = null) {
|
|
|
612
603
|
};
|
|
613
604
|
if (typeof html !== 'string')
|
|
614
605
|
return result;
|
|
615
|
-
const $ = cheerio.load(html, { decodeEntities: true });
|
|
606
|
+
const $ = cheerio.load(html, { xml: { decodeEntities: true } });
|
|
616
607
|
if (data)
|
|
617
608
|
data.$ = $;
|
|
618
|
-
const text =
|
|
609
|
+
const text = htmlToText($);
|
|
619
610
|
if (data)
|
|
620
611
|
data.text = text;
|
|
621
612
|
// NOTE: we need to parse each text separately, orherwise we might concatenate unrelated texts
|
|
@@ -638,14 +629,14 @@ function parseHandlesFromHtml(html, data = null) {
|
|
|
638
629
|
// https://www.linkedin.com/in/carl-newman-123456a/detail/recent-activity/
|
|
639
630
|
// they match just:
|
|
640
631
|
// https://www.linkedin.com/in/carl-newman-123456a
|
|
641
|
-
result.linkedIns = html.match(
|
|
642
|
-
result.twitters = html.match(
|
|
643
|
-
result.instagrams = html.match(
|
|
644
|
-
result.facebooks = html.match(
|
|
645
|
-
result.youtubes = html.match(
|
|
646
|
-
result.tiktoks = html.match(
|
|
647
|
-
result.pinterests = html.match(
|
|
648
|
-
result.discords = html.match(
|
|
632
|
+
result.linkedIns = html.match(LINKEDIN_REGEX_GLOBAL) || [];
|
|
633
|
+
result.twitters = html.match(TWITTER_REGEX_GLOBAL) || [];
|
|
634
|
+
result.instagrams = html.match(INSTAGRAM_REGEX_GLOBAL) || [];
|
|
635
|
+
result.facebooks = html.match(FACEBOOK_REGEX_GLOBAL) || [];
|
|
636
|
+
result.youtubes = html.match(YOUTUBE_REGEX_GLOBAL) || [];
|
|
637
|
+
result.tiktoks = html.match(TIKTOK_REGEX_GLOBAL) || [];
|
|
638
|
+
result.pinterests = html.match(PINTEREST_REGEX_GLOBAL) || [];
|
|
639
|
+
result.discords = html.match(DISCORD_REGEX_GLOBAL) || [];
|
|
649
640
|
// Sort and deduplicate handles
|
|
650
641
|
for (const key of Object.keys(result)) {
|
|
651
642
|
result[key].sort();
|
package/internals/social.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/internals/social.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/internals/social.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.getContainerCpuUsage = getContainerCpuUsage;
|
|
7
|
-
exports.getSystemCpuUsage = getSystemCpuUsage;
|
|
8
|
-
exports.sampleCpuUsage = sampleCpuUsage;
|
|
9
|
-
exports.getCurrentCpuTicksV2 = getCurrentCpuTicksV2;
|
|
10
|
-
const tslib_1 = require("tslib");
|
|
11
|
-
const node_child_process_1 = require("node:child_process");
|
|
12
|
-
const promises_1 = require("node:fs/promises");
|
|
13
|
-
const node_os_1 = tslib_1.__importDefault(require("node:os"));
|
|
14
|
-
const log_1 = tslib_1.__importDefault(require("@apify/log"));
|
|
15
|
-
const general_1 = require("../general");
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import log from '@apify/log';
|
|
5
|
+
import { getCgroupsVersion } from '../general.js';
|
|
16
6
|
const CPU_FILE_PATHS = {
|
|
17
7
|
STAT: {
|
|
18
8
|
V1: '/sys/fs/cgroup/cpuacct/cpuacct.usage',
|
|
@@ -40,8 +30,8 @@ const previousTicks = { idle: 0, total: 0 };
|
|
|
40
30
|
* @returns a number between 0 and 1 for the cpu load
|
|
41
31
|
* @internal
|
|
42
32
|
*/
|
|
43
|
-
function getCurrentCpuTicks() {
|
|
44
|
-
const cpusCores =
|
|
33
|
+
export function getCurrentCpuTicks() {
|
|
34
|
+
const cpusCores = os.cpus();
|
|
45
35
|
const ticks = cpusCores.reduce((acc, cpu) => {
|
|
46
36
|
const cpuTimes = Object.values(cpu.times);
|
|
47
37
|
return {
|
|
@@ -59,11 +49,11 @@ function getCurrentCpuTicks() {
|
|
|
59
49
|
*/
|
|
60
50
|
function getClockTicks() {
|
|
61
51
|
try {
|
|
62
|
-
const result =
|
|
52
|
+
const result = execSync('getconf CLK_TCK').toString().trim();
|
|
63
53
|
return parseInt(result, 10);
|
|
64
54
|
}
|
|
65
55
|
catch (err) {
|
|
66
|
-
|
|
56
|
+
log.warningOnce('Failed to get clock ticks; defaulting to 100');
|
|
67
57
|
return 100;
|
|
68
58
|
}
|
|
69
59
|
}
|
|
@@ -75,14 +65,14 @@ function getClockTicks() {
|
|
|
75
65
|
* @returns The Cpu Quota
|
|
76
66
|
* @internal
|
|
77
67
|
*/
|
|
78
|
-
async function getCpuQuota(cgroupsVersion) {
|
|
68
|
+
export async function getCpuQuota(cgroupsVersion) {
|
|
79
69
|
if (cgroupsVersion === 'V1') {
|
|
80
|
-
const quotaStr = await
|
|
70
|
+
const quotaStr = await readFile(CPU_FILE_PATHS.QUOTA.V1, 'utf8');
|
|
81
71
|
const quota = parseInt(quotaStr.trim(), 10);
|
|
82
72
|
return quota === -1 ? null : quota;
|
|
83
73
|
}
|
|
84
74
|
// cgroup v2
|
|
85
|
-
const maxStr = await
|
|
75
|
+
const maxStr = await readFile(CPU_FILE_PATHS.QUOTA.V2, 'utf8');
|
|
86
76
|
const parts = maxStr.trim().split(/\s+/);
|
|
87
77
|
if (parts[0] === 'max') {
|
|
88
78
|
return null;
|
|
@@ -95,14 +85,14 @@ async function getCpuQuota(cgroupsVersion) {
|
|
|
95
85
|
* @returns The Cpu quota period
|
|
96
86
|
* @internal
|
|
97
87
|
*/
|
|
98
|
-
async function getCpuPeriod(cgroupsVersion) {
|
|
88
|
+
export async function getCpuPeriod(cgroupsVersion) {
|
|
99
89
|
if (cgroupsVersion === 'V1') {
|
|
100
|
-
const quotaStr = await
|
|
90
|
+
const quotaStr = await readFile(CPU_FILE_PATHS.PERIOD.V1, 'utf8');
|
|
101
91
|
const quota = parseInt(quotaStr.trim(), 10);
|
|
102
92
|
return quota;
|
|
103
93
|
}
|
|
104
94
|
// cgroup v2
|
|
105
|
-
const maxStr = await
|
|
95
|
+
const maxStr = await readFile(CPU_FILE_PATHS.PERIOD.V2, 'utf8');
|
|
106
96
|
const parts = maxStr.trim().split(/\s+/);
|
|
107
97
|
return parseInt(parts[1], 10);
|
|
108
98
|
}
|
|
@@ -113,13 +103,13 @@ async function getCpuPeriod(cgroupsVersion) {
|
|
|
113
103
|
* @returns the cpu usage
|
|
114
104
|
* @internal
|
|
115
105
|
*/
|
|
116
|
-
async function getContainerCpuUsage(cgroupsVersion) {
|
|
106
|
+
export async function getContainerCpuUsage(cgroupsVersion) {
|
|
117
107
|
if (cgroupsVersion === 'V1') {
|
|
118
|
-
const data = await
|
|
108
|
+
const data = await readFile(CPU_FILE_PATHS.STAT.V1, 'utf8');
|
|
119
109
|
return Number(data.trim());
|
|
120
110
|
}
|
|
121
111
|
// cgroup v2
|
|
122
|
-
const data = await
|
|
112
|
+
const data = await readFile(CPU_FILE_PATHS.STAT.V2, 'utf8');
|
|
123
113
|
const lines = data.split('\n');
|
|
124
114
|
let usageUsec = 0;
|
|
125
115
|
for (const line of lines) {
|
|
@@ -138,8 +128,8 @@ async function getContainerCpuUsage(cgroupsVersion) {
|
|
|
138
128
|
* @returns the cpu usage
|
|
139
129
|
* @internal
|
|
140
130
|
*/
|
|
141
|
-
async function getSystemCpuUsage() {
|
|
142
|
-
const statData = await
|
|
131
|
+
export async function getSystemCpuUsage() {
|
|
132
|
+
const statData = await readFile('/proc/stat', 'utf8');
|
|
143
133
|
const lines = statData.split('\n');
|
|
144
134
|
for (const line of lines) {
|
|
145
135
|
if (line.startsWith('cpu ')) {
|
|
@@ -162,7 +152,7 @@ async function getSystemCpuUsage() {
|
|
|
162
152
|
* @returns An object containing the container and system CPU usage.
|
|
163
153
|
* @internal
|
|
164
154
|
*/
|
|
165
|
-
async function sampleCpuUsage(cGroupsVersion) {
|
|
155
|
+
export async function sampleCpuUsage(cGroupsVersion) {
|
|
166
156
|
const [containerUsage, systemUsage] = await Promise.all([
|
|
167
157
|
getContainerCpuUsage(cGroupsVersion),
|
|
168
158
|
getSystemCpuUsage(),
|
|
@@ -177,7 +167,7 @@ let previousSample = { containerUsage: 0, systemUsage: 0 };
|
|
|
177
167
|
* @returns a number between 0 and 1 for the cpu load
|
|
178
168
|
* @internal
|
|
179
169
|
*/
|
|
180
|
-
async function getCurrentCpuTicksV2(containerized = false) {
|
|
170
|
+
export async function getCurrentCpuTicksV2(containerized = false) {
|
|
181
171
|
try {
|
|
182
172
|
// if not containerized
|
|
183
173
|
if (!containerized) {
|
|
@@ -188,10 +178,10 @@ async function getCurrentCpuTicksV2(containerized = false) {
|
|
|
188
178
|
CLOCK_TICKS_PER_SECOND = getClockTicks();
|
|
189
179
|
CLOCK_TICKS_CHECKED = true;
|
|
190
180
|
}
|
|
191
|
-
const cgroupsVersion = await
|
|
181
|
+
const cgroupsVersion = await getCgroupsVersion();
|
|
192
182
|
// if cgroup is not detected, return bare metal cpu limit
|
|
193
183
|
if (cgroupsVersion === null) {
|
|
194
|
-
|
|
184
|
+
log.deprecated('Your environment is containerized, but your system does not support cgroups.\n' +
|
|
195
185
|
"If you're running containers with limited cpu, cpu auto-scaling will not work properly.");
|
|
196
186
|
return getCurrentCpuTicks();
|
|
197
187
|
}
|
|
@@ -208,13 +198,13 @@ async function getCurrentCpuTicksV2(containerized = false) {
|
|
|
208
198
|
const containerDelta = sample.containerUsage - previousSample.containerUsage;
|
|
209
199
|
const systemDelta = sample.systemUsage - previousSample.systemUsage;
|
|
210
200
|
previousSample = sample;
|
|
211
|
-
const numCpus =
|
|
201
|
+
const numCpus = os.cpus().length;
|
|
212
202
|
// Calculate the CPU usage percentage.
|
|
213
203
|
return ((containerDelta / systemDelta) * numCpus) / cpuAllowance;
|
|
214
204
|
}
|
|
215
205
|
catch (err) {
|
|
216
206
|
// if anything fails, default to bare metal metrics
|
|
217
|
-
|
|
207
|
+
log.exception(err, 'Cpu snapshot failed.');
|
|
218
208
|
return getCurrentCpuTicks();
|
|
219
209
|
}
|
|
220
210
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cpu-info.js","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/cpu-info.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cpu-info.js","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/cpu-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const node_os_1 = require("node:os");
|
|
8
|
-
const log_1 = tslib_1.__importDefault(require("@apify/log"));
|
|
9
|
-
const general_1 = require("../general");
|
|
10
|
-
const ps_tree_1 = require("./ps-tree");
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { freemem, totalmem } from 'node:os';
|
|
4
|
+
import log from '@apify/log';
|
|
5
|
+
import { getCgroupsVersion, isLambda } from '../general.js';
|
|
6
|
+
import { psTree } from './ps-tree.js';
|
|
11
7
|
const MEMORY_FILE_PATHS = {
|
|
12
8
|
TOTAL: {
|
|
13
9
|
V1: '/sys/fs/cgroup/memory/memory.limit_in_bytes',
|
|
@@ -29,16 +25,16 @@ const MEMORY_FILE_PATHS = {
|
|
|
29
25
|
* @returns An object containing the free and used memory metrics.
|
|
30
26
|
* @internal
|
|
31
27
|
*/
|
|
32
|
-
async function getMemoryInfoV2(containerized = false) {
|
|
28
|
+
export async function getMemoryInfoV2(containerized = false) {
|
|
33
29
|
let mainProcessBytes = -1;
|
|
34
30
|
let childProcessesBytes = 0;
|
|
35
31
|
// lambda does *not* have `ps` and other command line tools
|
|
36
32
|
// required to extract memory usage.
|
|
37
|
-
if (
|
|
33
|
+
if (isLambda()) {
|
|
38
34
|
// reported in bytes
|
|
39
35
|
mainProcessBytes = process.memoryUsage().rss;
|
|
40
36
|
// https://stackoverflow.com/a/55914335/129415
|
|
41
|
-
const memInfo =
|
|
37
|
+
const memInfo = execSync('cat /proc/meminfo').toString();
|
|
42
38
|
const values = memInfo.split(/[\n: ]/).filter((val) => val.trim());
|
|
43
39
|
// /proc/meminfo reports in kb, not bytes, the total used memory is reported by meminfo
|
|
44
40
|
// subtract memory used by the main node process in order to infer memory used by any child processes
|
|
@@ -46,7 +42,7 @@ async function getMemoryInfoV2(containerized = false) {
|
|
|
46
42
|
}
|
|
47
43
|
else {
|
|
48
44
|
// Query both root and child processes
|
|
49
|
-
const processes = await
|
|
45
|
+
const processes = await psTree(process.pid, true);
|
|
50
46
|
processes.forEach((rec) => {
|
|
51
47
|
// Obtain main process' memory separately
|
|
52
48
|
if (rec.PID === `${process.pid}`) {
|
|
@@ -59,23 +55,23 @@ async function getMemoryInfoV2(containerized = false) {
|
|
|
59
55
|
let totalBytes;
|
|
60
56
|
let usedBytes;
|
|
61
57
|
let freeBytes;
|
|
62
|
-
if (
|
|
58
|
+
if (isLambda()) {
|
|
63
59
|
// memory size is defined in megabytes
|
|
64
60
|
totalBytes = parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE, 10) * 1000000;
|
|
65
61
|
usedBytes = mainProcessBytes + childProcessesBytes;
|
|
66
62
|
freeBytes = totalBytes - usedBytes;
|
|
67
|
-
|
|
63
|
+
log.debug(`lambda size of ${totalBytes} with ${freeBytes} free bytes`);
|
|
68
64
|
}
|
|
69
65
|
else if (containerized) {
|
|
70
66
|
// When running inside a container, use container memory limits
|
|
71
|
-
const cgroupsVersion = await
|
|
67
|
+
const cgroupsVersion = await getCgroupsVersion();
|
|
72
68
|
try {
|
|
73
69
|
if (cgroupsVersion === null) {
|
|
74
70
|
throw new Error('cgroup not available');
|
|
75
71
|
}
|
|
76
72
|
let [totalBytesStr, usedBytesStr] = await Promise.all([
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
readFile(MEMORY_FILE_PATHS.TOTAL[cgroupsVersion], 'utf8'),
|
|
74
|
+
readFile(MEMORY_FILE_PATHS.USED[cgroupsVersion], 'utf8'),
|
|
79
75
|
]);
|
|
80
76
|
// Cgroups V2 files contains newline character. Getting rid of it for better handling in later part of the code.
|
|
81
77
|
totalBytesStr = totalBytesStr.replace(/[^a-zA-Z0-9 ]/g, '');
|
|
@@ -83,7 +79,7 @@ async function getMemoryInfoV2(containerized = false) {
|
|
|
83
79
|
// Cgroups V2 contains 'max' string if memory is not limited
|
|
84
80
|
// See https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git/tree/Documentation/admin-guide/cgroup-v2.rst (see "memory.max")
|
|
85
81
|
if (totalBytesStr === 'max') {
|
|
86
|
-
totalBytes =
|
|
82
|
+
totalBytes = totalmem();
|
|
87
83
|
// Cgroups V1 is set to number related to platform and page size if memory is not limited
|
|
88
84
|
// See https://unix.stackexchange.com/q/420906
|
|
89
85
|
}
|
|
@@ -91,24 +87,24 @@ async function getMemoryInfoV2(containerized = false) {
|
|
|
91
87
|
totalBytes = parseInt(totalBytesStr, 10);
|
|
92
88
|
const containerRunsWithUnlimitedMemory = totalBytes > Number.MAX_SAFE_INTEGER;
|
|
93
89
|
if (containerRunsWithUnlimitedMemory)
|
|
94
|
-
totalBytes =
|
|
90
|
+
totalBytes = totalmem();
|
|
95
91
|
}
|
|
96
92
|
usedBytes = parseInt(usedBytesStr, 10);
|
|
97
93
|
freeBytes = totalBytes - usedBytes;
|
|
98
94
|
}
|
|
99
95
|
catch (err) {
|
|
100
96
|
// log.deprecated logs a warning only once
|
|
101
|
-
|
|
97
|
+
log.deprecated('Your environment is containerized, but your system does not support memory cgroups. ' +
|
|
102
98
|
"If you're running containers with limited memory, memory auto-scaling will not work properly.\n\n" +
|
|
103
99
|
`Cause: ${err.message}`);
|
|
104
|
-
totalBytes =
|
|
105
|
-
freeBytes =
|
|
100
|
+
totalBytes = totalmem();
|
|
101
|
+
freeBytes = freemem();
|
|
106
102
|
usedBytes = totalBytes - freeBytes;
|
|
107
103
|
}
|
|
108
104
|
}
|
|
109
105
|
else {
|
|
110
|
-
totalBytes =
|
|
111
|
-
freeBytes =
|
|
106
|
+
totalBytes = totalmem();
|
|
107
|
+
freeBytes = freemem();
|
|
112
108
|
usedBytes = totalBytes - freeBytes;
|
|
113
109
|
}
|
|
114
110
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-info.js","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/memory-info.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-info.js","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/memory-info.ts"],"names":[],"mappings":"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"}
|