@crawlee/utils 3.12.3-beta.3 → 3.12.3-beta.31

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/README.md CHANGED
@@ -80,6 +80,28 @@ await crawler.run(['https://crawlee.dev']);
80
80
 
81
81
  By default, Crawlee stores data to `./storage` in the current working directory. You can override this directory via Crawlee configuration. For details, see [Configuration guide](https://crawlee.dev/docs/guides/configuration), [Request storage](https://crawlee.dev/docs/guides/request-storage) and [Result storage](https://crawlee.dev/docs/guides/result-storage).
82
82
 
83
+ ### Installing pre-release versions
84
+
85
+ We provide automated beta builds for every merged code change in Crawlee. You can find them in the npm [list of releases](https://www.npmjs.com/package/crawlee?activeTab=versions). If you want to test new features or bug fixes before we release them, feel free to install a beta build like this:
86
+
87
+ ```bash
88
+ npm install crawlee@3.12.3-beta.13
89
+ ```
90
+
91
+ If you also use the [Apify SDK](https://github.com/apify/apify-sdk-js), you need to specify dependency overrides in your `package.json` file so that you don't end up with multiple versions of Crawlee installed:
92
+
93
+ ```json
94
+ {
95
+ "overrides": {
96
+ "apify": {
97
+ "@crawlee/core": "3.12.3-beta.13",
98
+ "@crawlee/types": "3.12.3-beta.13",
99
+ "@crawlee/utils": "3.12.3-beta.13"
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
83
105
  ## 🛠 Features
84
106
 
85
107
  - Single interface for **HTTP and headless browser** crawling
package/index.d.ts CHANGED
@@ -12,5 +12,7 @@ export * from './internals/gotScraping';
12
12
  export * from './internals/robots';
13
13
  export * from './internals/sitemap';
14
14
  export * from './internals/url';
15
+ export { getCurrentCpuTicksV2 } from './internals/systemInfoV2/cpu-info';
16
+ export { getMemoryInfoV2 } from './internals/systemInfoV2/memory-info';
15
17
  export { Dictionary, Awaitable, Constructor } from '@crawlee/types';
16
18
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.social = void 0;
3
+ exports.getMemoryInfoV2 = exports.getCurrentCpuTicksV2 = exports.social = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  tslib_1.__exportStar(require("./internals/blocked"), exports);
6
6
  tslib_1.__exportStar(require("./internals/cheerio"), exports);
@@ -16,4 +16,8 @@ tslib_1.__exportStar(require("./internals/gotScraping"), exports);
16
16
  tslib_1.__exportStar(require("./internals/robots"), exports);
17
17
  tslib_1.__exportStar(require("./internals/sitemap"), exports);
18
18
  tslib_1.__exportStar(require("./internals/url"), exports);
19
+ var cpu_info_1 = require("./internals/systemInfoV2/cpu-info");
20
+ Object.defineProperty(exports, "getCurrentCpuTicksV2", { enumerable: true, get: function () { return cpu_info_1.getCurrentCpuTicksV2; } });
21
+ var memory_info_1 = require("./internals/systemInfoV2/memory-info");
22
+ Object.defineProperty(exports, "getMemoryInfoV2", { enumerable: true, get: function () { return memory_info_1.getMemoryInfoV2; } });
19
23
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,8DAAoC;AACpC,8DAAoC;AACpC,4DAAkC;AAClC,mEAAyC;AACzC,8DAAoC;AACpC,kEAAwC;AACxC,4DAAkC;AAClC,qEAA6C;AAC7C,+DAAqC;AACrC,wEAA8C;AAC9C,kEAAwC;AACxC,6DAAmC;AACnC,8DAAoC;AACpC,0DAAgC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,8DAAoC;AACpC,8DAAoC;AACpC,4DAAkC;AAClC,mEAAyC;AACzC,8DAAoC;AACpC,kEAAwC;AACxC,4DAAkC;AAClC,qEAA6C;AAC7C,+DAAqC;AACrC,wEAA8C;AAC9C,kEAAwC;AACxC,6DAAmC;AACnC,8DAAoC;AACpC,0DAAgC;AAEhC,8DAAyE;AAAhE,gHAAA,oBAAoB,OAAA;AAC7B,oEAAuE;AAA9D,8GAAA,eAAe,OAAA"}
package/index.mjs CHANGED
@@ -16,10 +16,15 @@ export const entries = mod.entries;
16
16
  export const expandShadowRoots = mod.expandShadowRoots;
17
17
  export const extractUrls = mod.extractUrls;
18
18
  export const extractUrlsFromCheerio = mod.extractUrlsFromCheerio;
19
+ export const getCgroupsVersion = mod.getCgroupsVersion;
20
+ export const getCurrentCpuTicksV2 = mod.getCurrentCpuTicksV2;
19
21
  export const getMemoryInfo = mod.getMemoryInfo;
22
+ export const getMemoryInfoV2 = mod.getMemoryInfoV2;
20
23
  export const gotScraping = mod.gotScraping;
21
24
  export const htmlToText = mod.htmlToText;
25
+ export const isContainerized = mod.isContainerized;
22
26
  export const isDocker = mod.isDocker;
27
+ export const isLambda = mod.isLambda;
23
28
  export const keys = mod.keys;
24
29
  export const parseOpenGraph = mod.parseOpenGraph;
25
30
  export const parseSitemap = mod.parseSitemap;
@@ -12,6 +12,16 @@ export declare const URL_WITH_COMMAS_REGEX: RegExp;
12
12
  * Returns a `Promise` that resolves to true if the code is running in a Docker container.
13
13
  */
14
14
  export declare function isDocker(forceReset?: boolean): Promise<boolean>;
15
+ /**
16
+ * Detects if crawlee is running in a containerized environment.
17
+ */
18
+ export declare function isContainerized(): Promise<boolean>;
19
+ export declare function isLambda(): boolean;
20
+ /**
21
+ * gets the cgroup version by checking for a file at /sys/fs/cgroup/memory
22
+ * @returns "V1" or "V2" for the version of cgroup or null if cgroup is not found.
23
+ */
24
+ export declare function getCgroupsVersion(forceReset?: boolean): Promise<"V1" | "V2" | null>;
15
25
  /**
16
26
  * Computes a weighted average of an array of numbers, complemented by an array of weights.
17
27
  * @ignore
@@ -1 +1 @@
1
- {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAC+G,CAAC;AAEhJ;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAC8G,CAAC;AAoBjJ;;GAEG;AACH,wBAAsB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAKrE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAW7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA8B5D"}
1
+ {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAC+G,CAAC;AAEhJ;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAC8G,CAAC;AAoBjJ;;GAEG;AACH,wBAAsB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAKrE;AAID;;GAEG;AACH,wBAAsB,eAAe,qBA0BpC;AAED,wBAAgB,QAAQ,YAEvB;AAGD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,OAAO,+BAoB3D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAW7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA8B5D"}
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.URL_WITH_COMMAS_REGEX = exports.URL_NO_COMMAS_REGEX = void 0;
4
4
  exports.isDocker = isDocker;
5
+ exports.isContainerized = isContainerized;
6
+ exports.isLambda = isLambda;
7
+ exports.getCgroupsVersion = getCgroupsVersion;
5
8
  exports.weightedAvg = weightedAvg;
6
9
  exports.sleep = sleep;
7
10
  exports.snakeCaseToCamelCase = snakeCaseToCamelCase;
@@ -41,6 +44,63 @@ async function isDocker(forceReset) {
41
44
  isDockerPromiseCache = createIsDockerPromise();
42
45
  return isDockerPromiseCache;
43
46
  }
47
+ let isContainerizedResult;
48
+ /**
49
+ * Detects if crawlee is running in a containerized environment.
50
+ */
51
+ async function isContainerized() {
52
+ // Value is very unlikley to change. Cache the result after the first execution.
53
+ if (isContainerizedResult !== undefined) {
54
+ return isContainerizedResult;
55
+ }
56
+ // return false if running in aws lambda
57
+ if (isLambda()) {
58
+ isContainerizedResult = false;
59
+ return isContainerizedResult;
60
+ }
61
+ const dockerenvCheck = promises_1.default
62
+ .stat('/.dockerenv')
63
+ .then(() => true)
64
+ .catch(() => false);
65
+ const cgroupCheck = promises_1.default
66
+ .readFile('/proc/self/cgroup', 'utf8')
67
+ .then((content) => content.includes('docker'))
68
+ .catch(() => false);
69
+ const [dockerenvResult, cgroupResult] = await Promise.all([dockerenvCheck, cgroupCheck]);
70
+ isContainerizedResult = dockerenvResult || cgroupResult || !!process.env.KUBERNETES_SERVICE_HOST;
71
+ return isContainerizedResult;
72
+ }
73
+ function isLambda() {
74
+ return !!process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE;
75
+ }
76
+ let _cgroupsVersion;
77
+ /**
78
+ * gets the cgroup version by checking for a file at /sys/fs/cgroup/memory
79
+ * @returns "V1" or "V2" for the version of cgroup or null if cgroup is not found.
80
+ */
81
+ async function getCgroupsVersion(forceReset) {
82
+ // Parameter forceReset is just internal for unit tests.
83
+ if (_cgroupsVersion !== undefined && !forceReset) {
84
+ return _cgroupsVersion;
85
+ }
86
+ try {
87
+ // If this directory does not exists, cgroups are not available
88
+ await promises_1.default.access('/sys/fs/cgroup/');
89
+ }
90
+ catch (e) {
91
+ _cgroupsVersion = null;
92
+ return null;
93
+ }
94
+ _cgroupsVersion = 'V1';
95
+ try {
96
+ // If this directory does not exists, assume the container is using cgroups V2
97
+ await promises_1.default.access('/sys/fs/cgroup/memory/');
98
+ }
99
+ catch (e) {
100
+ _cgroupsVersion = 'V2';
101
+ }
102
+ return _cgroupsVersion;
103
+ }
44
104
  /**
45
105
  * Computes a weighted average of an array of numbers, complemented by an array of weights.
46
106
  * @ignore
@@ -1 +1 @@
1
- {"version":3,"file":"general.js","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"general.js","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Gets the "bare metal" cpu load.
3
+ * Used in
4
+ * - AWS Lambda
5
+ * - Containers without a cGroup quota
6
+ * - Uncontainerized environments
7
+ * @returns a number between 0 and 1 for the cpu load
8
+ * @internal
9
+ */
10
+ export declare function getCurrentCpuTicks(): number;
11
+ /**
12
+ * Reads the cgroup cpu quota.
13
+ * In V1, a quota of -1 means “unlimited.”
14
+ * In V2, a first field of "max" means unlimited.
15
+ * @param cgroupsVersion the cGroup version
16
+ * @returns The Cpu Quota
17
+ * @internal
18
+ */
19
+ export declare function getCpuQuota(cgroupsVersion: string): Promise<number | null>;
20
+ /**
21
+ * Reads the cgroup cpu period.
22
+ * @param cgroupsVersion the cGroup version
23
+ * @returns The Cpu quota period
24
+ * @internal
25
+ */
26
+ export declare function getCpuPeriod(cgroupsVersion: string): Promise<number>;
27
+ /**
28
+ * Reads the cgroup cpu usage of the container
29
+ *
30
+ * @param cgroupsVersion the cGroup version
31
+ * @returns the cpu usage
32
+ * @internal
33
+ */
34
+ export declare function getContainerCpuUsage(cgroupsVersion: string): Promise<number>;
35
+ /**
36
+ * Reads the cgroup cpu usage of the system from cgroup
37
+ *
38
+ * @returns the cpu usage
39
+ * @internal
40
+ */
41
+ export declare function getSystemCpuUsage(): Promise<number>;
42
+ /**
43
+ * a cpu sample with the container usage and system usage
44
+ */
45
+ export interface CpuSample {
46
+ containerUsage: number;
47
+ systemUsage: number;
48
+ }
49
+ /**
50
+ * Takes a CPU usage sample for both the container and the system.
51
+ *
52
+ * @returns An object containing the container and system CPU usage.
53
+ * @internal
54
+ */
55
+ export declare function sampleCpuUsage(cGroupsVersion: string): Promise<CpuSample>;
56
+ /**
57
+ * Gets the cpu usage of the system.
58
+ * If the crawler is running in a containerized environment, crawlee will check for a cgroup enforced cpu limit.
59
+ * If a cgroup limit is found, it will be taken as the maximum load against which the current load will be gauged.
60
+ * @returns a number between 0 and 1 for the cpu load
61
+ * @internal
62
+ */
63
+ export declare function getCurrentCpuTicksV2(containerized?: boolean): Promise<number>;
64
+ //# sourceMappingURL=cpu-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpu-info.d.ts","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/cpu-info.ts"],"names":[],"mappings":"AA6BA;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,WAejC;AAgBD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAahF;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBlF;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,oBAiBtC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAM/E;AAID;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CjF"}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCurrentCpuTicks = getCurrentCpuTicks;
4
+ exports.getCpuQuota = getCpuQuota;
5
+ exports.getCpuPeriod = getCpuPeriod;
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");
16
+ const CPU_FILE_PATHS = {
17
+ STAT: {
18
+ V1: '/sys/fs/cgroup/cpuacct/cpuacct.usage',
19
+ V2: '/sys/fs/cgroup/cpu.stat',
20
+ },
21
+ QUOTA: {
22
+ V1: '/sys/fs/cgroup/cpu/cpu.cfs_quota_us',
23
+ V2: '/sys/fs/cgroup/cpu.max',
24
+ },
25
+ PERIOD: {
26
+ V1: '/sys/fs/cgroup/cpu/cpu.cfs_period_us',
27
+ V2: '/sys/fs/cgroup/cpu.max',
28
+ },
29
+ };
30
+ let CLOCK_TICKS_PER_SECOND = 100;
31
+ let CLOCK_TICKS_CHECKED = false;
32
+ const NANOSECONDS_PER_SECOND = 1e9;
33
+ const previousTicks = { idle: 0, total: 0 };
34
+ /**
35
+ * Gets the "bare metal" cpu load.
36
+ * Used in
37
+ * - AWS Lambda
38
+ * - Containers without a cGroup quota
39
+ * - Uncontainerized environments
40
+ * @returns a number between 0 and 1 for the cpu load
41
+ * @internal
42
+ */
43
+ function getCurrentCpuTicks() {
44
+ const cpusCores = node_os_1.default.cpus();
45
+ const ticks = cpusCores.reduce((acc, cpu) => {
46
+ const cpuTimes = Object.values(cpu.times);
47
+ return {
48
+ idle: acc.idle + cpu.times.idle,
49
+ total: acc.total + cpuTimes.reduce((sum, num) => sum + num),
50
+ };
51
+ }, { idle: 0, total: 0 });
52
+ const idleTicksDelta = ticks.idle - previousTicks.idle;
53
+ const totalTicksDelta = ticks.total - previousTicks.total;
54
+ return totalTicksDelta ? 1 - idleTicksDelta / totalTicksDelta : 0;
55
+ }
56
+ /**
57
+ * Reads the linux tick rate
58
+ * @returns the number of ticks per second
59
+ */
60
+ function getClockTicks() {
61
+ try {
62
+ const result = (0, node_child_process_1.execSync)('getconf CLK_TCK').toString().trim();
63
+ return parseInt(result, 10);
64
+ }
65
+ catch (err) {
66
+ log_1.default.warningOnce('Failed to get clock ticks; defaulting to 100');
67
+ return 100;
68
+ }
69
+ }
70
+ /**
71
+ * Reads the cgroup cpu quota.
72
+ * In V1, a quota of -1 means “unlimited.”
73
+ * In V2, a first field of "max" means unlimited.
74
+ * @param cgroupsVersion the cGroup version
75
+ * @returns The Cpu Quota
76
+ * @internal
77
+ */
78
+ async function getCpuQuota(cgroupsVersion) {
79
+ if (cgroupsVersion === 'V1') {
80
+ const quotaStr = await (0, promises_1.readFile)(CPU_FILE_PATHS.QUOTA.V1, 'utf8');
81
+ const quota = parseInt(quotaStr.trim(), 10);
82
+ return quota === -1 ? null : quota;
83
+ }
84
+ // cgroup v2
85
+ const maxStr = await (0, promises_1.readFile)(CPU_FILE_PATHS.QUOTA.V2, 'utf8');
86
+ const parts = maxStr.trim().split(/\s+/);
87
+ if (parts[0] === 'max') {
88
+ return null;
89
+ }
90
+ return parseInt(parts[0], 10);
91
+ }
92
+ /**
93
+ * Reads the cgroup cpu period.
94
+ * @param cgroupsVersion the cGroup version
95
+ * @returns The Cpu quota period
96
+ * @internal
97
+ */
98
+ async function getCpuPeriod(cgroupsVersion) {
99
+ if (cgroupsVersion === 'V1') {
100
+ const quotaStr = await (0, promises_1.readFile)(CPU_FILE_PATHS.PERIOD.V1, 'utf8');
101
+ const quota = parseInt(quotaStr.trim(), 10);
102
+ return quota;
103
+ }
104
+ // cgroup v2
105
+ const maxStr = await (0, promises_1.readFile)(CPU_FILE_PATHS.PERIOD.V2, 'utf8');
106
+ const parts = maxStr.trim().split(/\s+/);
107
+ return parseInt(parts[1], 10);
108
+ }
109
+ /**
110
+ * Reads the cgroup cpu usage of the container
111
+ *
112
+ * @param cgroupsVersion the cGroup version
113
+ * @returns the cpu usage
114
+ * @internal
115
+ */
116
+ async function getContainerCpuUsage(cgroupsVersion) {
117
+ if (cgroupsVersion === 'V1') {
118
+ const data = await (0, promises_1.readFile)(CPU_FILE_PATHS.STAT.V1, 'utf8');
119
+ return Number(data.trim());
120
+ }
121
+ // cgroup v2
122
+ const data = await (0, promises_1.readFile)(CPU_FILE_PATHS.STAT.V2, 'utf8');
123
+ const lines = data.split('\n');
124
+ let usageUsec = 0;
125
+ for (const line of lines) {
126
+ const parts = line.trim().split(/\s+/);
127
+ if (parts[0] === 'usage_usec') {
128
+ usageUsec = Number(parts[1]);
129
+ break;
130
+ }
131
+ }
132
+ // Convert microseconds to nanoseconds.
133
+ return usageUsec * 1000;
134
+ }
135
+ /**
136
+ * Reads the cgroup cpu usage of the system from cgroup
137
+ *
138
+ * @returns the cpu usage
139
+ * @internal
140
+ */
141
+ async function getSystemCpuUsage() {
142
+ const statData = await (0, promises_1.readFile)('/proc/stat', 'utf8');
143
+ const lines = statData.split('\n');
144
+ for (const line of lines) {
145
+ if (line.startsWith('cpu ')) {
146
+ // Split the line and extract the first seven numeric fields:
147
+ // user, nice, system, idle, iowait, irq, softirq
148
+ const parts = line.split(/\s+/).slice(1, 8);
149
+ let totalTicks = 0;
150
+ for (const part of parts) {
151
+ totalTicks += Number(part);
152
+ }
153
+ // Convert clock ticks to nanoseconds.
154
+ return (totalTicks * NANOSECONDS_PER_SECOND) / CLOCK_TICKS_PER_SECOND;
155
+ }
156
+ }
157
+ throw new Error('no cpu line'); // shouldnt ever happen
158
+ }
159
+ /**
160
+ * Takes a CPU usage sample for both the container and the system.
161
+ *
162
+ * @returns An object containing the container and system CPU usage.
163
+ * @internal
164
+ */
165
+ async function sampleCpuUsage(cGroupsVersion) {
166
+ const [containerUsage, systemUsage] = await Promise.all([
167
+ getContainerCpuUsage(cGroupsVersion),
168
+ getSystemCpuUsage(),
169
+ ]);
170
+ return { containerUsage, systemUsage };
171
+ }
172
+ let previousSample = { containerUsage: 0, systemUsage: 0 };
173
+ /**
174
+ * Gets the cpu usage of the system.
175
+ * If the crawler is running in a containerized environment, crawlee will check for a cgroup enforced cpu limit.
176
+ * If a cgroup limit is found, it will be taken as the maximum load against which the current load will be gauged.
177
+ * @returns a number between 0 and 1 for the cpu load
178
+ * @internal
179
+ */
180
+ async function getCurrentCpuTicksV2(containerized = false) {
181
+ try {
182
+ // if not containerized
183
+ if (!containerized) {
184
+ // bare metal cpu limit
185
+ return getCurrentCpuTicks();
186
+ }
187
+ if (!CLOCK_TICKS_CHECKED) {
188
+ CLOCK_TICKS_PER_SECOND = getClockTicks();
189
+ CLOCK_TICKS_CHECKED = true;
190
+ }
191
+ const cgroupsVersion = await (0, general_1.getCgroupsVersion)();
192
+ // if cgroup is not detected, return bare metal cpu limit
193
+ if (cgroupsVersion === null) {
194
+ log_1.default.deprecated('Your environment is containerized, but your system does not support cgroups.\n' +
195
+ "If you're running containers with limited cpu, cpu auto-scaling will not work properly.");
196
+ return getCurrentCpuTicks();
197
+ }
198
+ // cgroup aware cpu limit. If no limits are set, default to returning getCurrentCpuTicks.
199
+ const quota = await getCpuQuota(cgroupsVersion);
200
+ if (quota === null) {
201
+ // no cgroup limit, return host cpu load
202
+ return getCurrentCpuTicks();
203
+ }
204
+ const period = await getCpuPeriod(cgroupsVersion);
205
+ // eg. having a 200000us quots per 100000us means the cGroup can fully use 2 cores
206
+ const cpuAllowance = quota / period;
207
+ const sample = await sampleCpuUsage(cgroupsVersion);
208
+ const containerDelta = sample.containerUsage - previousSample.containerUsage;
209
+ const systemDelta = sample.systemUsage - previousSample.systemUsage;
210
+ previousSample = sample;
211
+ const numCpus = node_os_1.default.cpus().length;
212
+ // Calculate the CPU usage percentage.
213
+ return ((containerDelta / systemDelta) * numCpus) / cpuAllowance;
214
+ }
215
+ catch (err) {
216
+ // if anything fails, default to bare metal metrics
217
+ log_1.default.exception(err, 'Cpu snapshot failed.');
218
+ return getCurrentCpuTicks();
219
+ }
220
+ }
221
+ //# sourceMappingURL=cpu-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpu-info.js","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/cpu-info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Describes memory usage of the process.
3
+ */
4
+ export interface MemoryInfo {
5
+ /** Total memory available in the system or container */
6
+ totalBytes: number;
7
+ /** Amount of free memory in the system or container */
8
+ freeBytes: number;
9
+ /** Amount of memory used (= totalBytes - freeBytes) */
10
+ usedBytes: number;
11
+ /** Amount of memory used the current Node.js process */
12
+ mainProcessBytes: number;
13
+ /** Amount of memory used by child processes of the current Node.js process */
14
+ childProcessesBytes: number;
15
+ }
16
+ /**
17
+ * Returns memory statistics of the process and the system, see {@apilink MemoryInfo}.
18
+ *
19
+ * If the process runs inside of a container, the `getMemoryInfo` gets container memory limits,
20
+ * otherwise it gets system memory limits.
21
+ *
22
+ * Beware that the function is quite inefficient because it spawns a new process.
23
+ * Therefore you shouldn't call it too often, like more than once per second.
24
+ * @returns An object containing the free and used memory metrics.
25
+ * @internal
26
+ */
27
+ export declare function getMemoryInfoV2(containerized?: boolean): Promise<MemoryInfo>;
28
+ //# sourceMappingURL=memory-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-info.d.ts","sourceRoot":"","sources":["../../../src/internals/systemInfoV2/memory-info.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IAEnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAElB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAElB,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8EAA8E;IAC9E,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,aAAa,UAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAgGhF"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMemoryInfoV2 = getMemoryInfoV2;
4
+ const tslib_1 = require("tslib");
5
+ const node_child_process_1 = require("node:child_process");
6
+ const promises_1 = require("node:fs/promises");
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");
11
+ const MEMORY_FILE_PATHS = {
12
+ TOTAL: {
13
+ V1: '/sys/fs/cgroup/memory/memory.limit_in_bytes',
14
+ V2: '/sys/fs/cgroup/memory.max',
15
+ },
16
+ USED: {
17
+ V1: '/sys/fs/cgroup/memory/memory.usage_in_bytes',
18
+ V2: '/sys/fs/cgroup/memory.current',
19
+ },
20
+ };
21
+ /**
22
+ * Returns memory statistics of the process and the system, see {@apilink MemoryInfo}.
23
+ *
24
+ * If the process runs inside of a container, the `getMemoryInfo` gets container memory limits,
25
+ * otherwise it gets system memory limits.
26
+ *
27
+ * Beware that the function is quite inefficient because it spawns a new process.
28
+ * Therefore you shouldn't call it too often, like more than once per second.
29
+ * @returns An object containing the free and used memory metrics.
30
+ * @internal
31
+ */
32
+ async function getMemoryInfoV2(containerized = false) {
33
+ let mainProcessBytes = -1;
34
+ let childProcessesBytes = 0;
35
+ // lambda does *not* have `ps` and other command line tools
36
+ // required to extract memory usage.
37
+ if ((0, general_1.isLambda)()) {
38
+ // reported in bytes
39
+ mainProcessBytes = process.memoryUsage().rss;
40
+ // https://stackoverflow.com/a/55914335/129415
41
+ const memInfo = (0, node_child_process_1.execSync)('cat /proc/meminfo').toString();
42
+ const values = memInfo.split(/[\n: ]/).filter((val) => val.trim());
43
+ // /proc/meminfo reports in kb, not bytes, the total used memory is reported by meminfo
44
+ // subtract memory used by the main node process in order to infer memory used by any child processes
45
+ childProcessesBytes = +values[19] * 1000 - mainProcessBytes;
46
+ }
47
+ else {
48
+ // Query both root and child processes
49
+ const processes = await (0, ps_tree_1.psTree)(process.pid, true);
50
+ processes.forEach((rec) => {
51
+ // Obtain main process' memory separately
52
+ if (rec.PID === `${process.pid}`) {
53
+ mainProcessBytes = rec.RSS;
54
+ return;
55
+ }
56
+ childProcessesBytes += rec.RSS;
57
+ });
58
+ }
59
+ let totalBytes;
60
+ let usedBytes;
61
+ let freeBytes;
62
+ if ((0, general_1.isLambda)()) {
63
+ // memory size is defined in megabytes
64
+ totalBytes = parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE, 10) * 1000000;
65
+ usedBytes = mainProcessBytes + childProcessesBytes;
66
+ freeBytes = totalBytes - usedBytes;
67
+ log_1.default.debug(`lambda size of ${totalBytes} with ${freeBytes} free bytes`);
68
+ }
69
+ else if (containerized) {
70
+ // When running inside a container, use container memory limits
71
+ const cgroupsVersion = await (0, general_1.getCgroupsVersion)();
72
+ try {
73
+ if (cgroupsVersion === null) {
74
+ throw new Error('cgroup not available');
75
+ }
76
+ let [totalBytesStr, usedBytesStr] = await Promise.all([
77
+ (0, promises_1.readFile)(MEMORY_FILE_PATHS.TOTAL[cgroupsVersion], 'utf8'),
78
+ (0, promises_1.readFile)(MEMORY_FILE_PATHS.USED[cgroupsVersion], 'utf8'),
79
+ ]);
80
+ // Cgroups V2 files contains newline character. Getting rid of it for better handling in later part of the code.
81
+ totalBytesStr = totalBytesStr.replace(/[^a-zA-Z0-9 ]/g, '');
82
+ usedBytesStr = usedBytesStr.replace(/[^a-zA-Z0-9 ]/g, '');
83
+ // Cgroups V2 contains 'max' string if memory is not limited
84
+ // See https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git/tree/Documentation/admin-guide/cgroup-v2.rst (see "memory.max")
85
+ if (totalBytesStr === 'max') {
86
+ totalBytes = (0, node_os_1.totalmem)();
87
+ // Cgroups V1 is set to number related to platform and page size if memory is not limited
88
+ // See https://unix.stackexchange.com/q/420906
89
+ }
90
+ else {
91
+ totalBytes = parseInt(totalBytesStr, 10);
92
+ const containerRunsWithUnlimitedMemory = totalBytes > Number.MAX_SAFE_INTEGER;
93
+ if (containerRunsWithUnlimitedMemory)
94
+ totalBytes = (0, node_os_1.totalmem)();
95
+ }
96
+ usedBytes = parseInt(usedBytesStr, 10);
97
+ freeBytes = totalBytes - usedBytes;
98
+ }
99
+ catch (err) {
100
+ // log.deprecated logs a warning only once
101
+ log_1.default.deprecated('Your environment is containerized, but your system does not support memory cgroups. ' +
102
+ "If you're running containers with limited memory, memory auto-scaling will not work properly.\n\n" +
103
+ `Cause: ${err.message}`);
104
+ totalBytes = (0, node_os_1.totalmem)();
105
+ freeBytes = (0, node_os_1.freemem)();
106
+ usedBytes = totalBytes - freeBytes;
107
+ }
108
+ }
109
+ else {
110
+ totalBytes = (0, node_os_1.totalmem)();
111
+ freeBytes = (0, node_os_1.freemem)();
112
+ usedBytes = totalBytes - freeBytes;
113
+ }
114
+ return {
115
+ totalBytes,
116
+ freeBytes,
117
+ usedBytes,
118
+ mainProcessBytes,
119
+ childProcessesBytes,
120
+ };
121
+ }
122
+ //# sourceMappingURL=memory-info.js.map