wattpm 3.7.1 → 3.9.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/lib/commands/pprof.js +46 -21
- package/package.json +5 -5
- package/schema.json +68 -3
package/lib/commands/pprof.js
CHANGED
|
@@ -5,7 +5,15 @@ import { writeFile } from 'node:fs/promises'
|
|
|
5
5
|
|
|
6
6
|
export async function pprofStartCommand (logger, args) {
|
|
7
7
|
try {
|
|
8
|
-
const { positionals } = parseArgs(args, {
|
|
8
|
+
const { positionals, values } = parseArgs(args, {
|
|
9
|
+
type: { type: 'string', short: 't', default: 'cpu' }
|
|
10
|
+
}, false)
|
|
11
|
+
|
|
12
|
+
// Validate profile type
|
|
13
|
+
const type = values.type
|
|
14
|
+
if (type !== 'cpu' && type !== 'heap') {
|
|
15
|
+
return logFatalError(logger, `Invalid profile type: ${type}. Must be 'cpu' or 'heap'.`)
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
const client = new RuntimeApiClient()
|
|
11
19
|
const [runtime, remainingPositionals] = await getMatchingRuntime(client, positionals)
|
|
@@ -14,6 +22,8 @@ export async function pprofStartCommand (logger, args) {
|
|
|
14
22
|
// Get application ID from positional arguments or use all applications
|
|
15
23
|
const applicationId = remainingPositionals[0]
|
|
16
24
|
|
|
25
|
+
const options = { intervalMicros: 1000, type }
|
|
26
|
+
|
|
17
27
|
if (applicationId) {
|
|
18
28
|
// Start profiling for specific application
|
|
19
29
|
const application = runtimeApplications.find(s => s.id === applicationId)
|
|
@@ -22,14 +32,14 @@ export async function pprofStartCommand (logger, args) {
|
|
|
22
32
|
return logFatalError(logger, `Application not found: ${applicationId}`)
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
await client.startApplicationProfiling(runtime.pid, applicationId,
|
|
26
|
-
logger.info(
|
|
35
|
+
await client.startApplicationProfiling(runtime.pid, applicationId, options)
|
|
36
|
+
logger.info(`${type.toUpperCase()} profiling started for application ${bold(applicationId)}`)
|
|
27
37
|
} else {
|
|
28
38
|
// Start profiling for all applications
|
|
29
39
|
for (const application of runtimeApplications) {
|
|
30
40
|
try {
|
|
31
|
-
await client.startApplicationProfiling(runtime.pid, application.id,
|
|
32
|
-
logger.info(
|
|
41
|
+
await client.startApplicationProfiling(runtime.pid, application.id, options)
|
|
42
|
+
logger.info(`${type.toUpperCase()} profiling started for application ${bold(application.id)}`)
|
|
33
43
|
} catch (error) {
|
|
34
44
|
logger.warn(`Failed to start profiling for application ${application.id}: ${error.message}`)
|
|
35
45
|
}
|
|
@@ -50,7 +60,15 @@ export async function pprofStartCommand (logger, args) {
|
|
|
50
60
|
|
|
51
61
|
export async function pprofStopCommand (logger, args) {
|
|
52
62
|
try {
|
|
53
|
-
const { positionals } = parseArgs(args, {
|
|
63
|
+
const { positionals, values } = parseArgs(args, {
|
|
64
|
+
type: { type: 'string', short: 't', default: 'cpu' }
|
|
65
|
+
}, false)
|
|
66
|
+
|
|
67
|
+
// Validate profile type
|
|
68
|
+
const type = values.type
|
|
69
|
+
if (type !== 'cpu' && type !== 'heap') {
|
|
70
|
+
return logFatalError(logger, `Invalid profile type: ${type}. Must be 'cpu' or 'heap'.`)
|
|
71
|
+
}
|
|
54
72
|
|
|
55
73
|
const client = new RuntimeApiClient()
|
|
56
74
|
const [runtime, remainingPositionals] = await getMatchingRuntime(client, positionals)
|
|
@@ -60,6 +78,8 @@ export async function pprofStopCommand (logger, args) {
|
|
|
60
78
|
const applicationId = remainingPositionals[0]
|
|
61
79
|
const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\./g, '-')
|
|
62
80
|
|
|
81
|
+
const options = { type }
|
|
82
|
+
|
|
63
83
|
if (applicationId) {
|
|
64
84
|
// Stop profiling for specific application
|
|
65
85
|
const application = runtimeApplications.find(s => s.id === applicationId)
|
|
@@ -68,18 +88,18 @@ export async function pprofStopCommand (logger, args) {
|
|
|
68
88
|
return logFatalError(logger, `Application not found: ${applicationId}`)
|
|
69
89
|
}
|
|
70
90
|
|
|
71
|
-
const profileData = await client.stopApplicationProfiling(runtime.pid, applicationId)
|
|
72
|
-
const filename = `pprof-${applicationId}-${timestamp}.pb`
|
|
91
|
+
const profileData = await client.stopApplicationProfiling(runtime.pid, applicationId, options)
|
|
92
|
+
const filename = `pprof-${type}-${applicationId}-${timestamp}.pb`
|
|
73
93
|
await writeFile(filename, Buffer.from(profileData))
|
|
74
|
-
logger.info(
|
|
94
|
+
logger.info(`${type.toUpperCase()} profiling stopped for application ${bold(applicationId)}, profile saved to ${bold(filename)}`)
|
|
75
95
|
} else {
|
|
76
96
|
// Stop profiling for all applications
|
|
77
97
|
for (const application of runtimeApplications) {
|
|
78
98
|
try {
|
|
79
|
-
const profileData = await client.stopApplicationProfiling(runtime.pid, application.id)
|
|
80
|
-
const filename = `pprof-${application.id}-${timestamp}.pb`
|
|
99
|
+
const profileData = await client.stopApplicationProfiling(runtime.pid, application.id, options)
|
|
100
|
+
const filename = `pprof-${type}-${application.id}-${timestamp}.pb`
|
|
81
101
|
await writeFile(filename, Buffer.from(profileData))
|
|
82
|
-
logger.info(
|
|
102
|
+
logger.info(`${type.toUpperCase()} profiling stopped for application ${bold(application.id)}, profile saved to ${bold(filename)}`)
|
|
83
103
|
} catch (error) {
|
|
84
104
|
logger.warn(`Failed to stop profiling for application ${application.id}: ${error.message}`)
|
|
85
105
|
}
|
|
@@ -113,9 +133,14 @@ export async function pprofCommand (logger, args) {
|
|
|
113
133
|
|
|
114
134
|
export const help = {
|
|
115
135
|
pprof: {
|
|
116
|
-
usage: 'pprof <start|stop> [id] [application]',
|
|
117
|
-
description: 'Profile CPU usage of running application',
|
|
118
|
-
options: [
|
|
136
|
+
usage: 'pprof <start|stop> [id] [application] [options]',
|
|
137
|
+
description: 'Profile CPU or heap usage of running application',
|
|
138
|
+
options: [
|
|
139
|
+
{
|
|
140
|
+
name: '--type, -t',
|
|
141
|
+
description: 'Profile type: "cpu" for CPU wall time (default) or "heap" for heap memory'
|
|
142
|
+
}
|
|
143
|
+
],
|
|
119
144
|
args: [
|
|
120
145
|
{
|
|
121
146
|
name: 'command',
|
|
@@ -126,17 +151,17 @@ export const help = {
|
|
|
126
151
|
description:
|
|
127
152
|
'The process ID or the name of the application (it can be omitted only if there is a single application running)'
|
|
128
153
|
},
|
|
129
|
-
{
|
|
130
|
-
name: 'id',
|
|
131
|
-
description:
|
|
132
|
-
'The process ID or the name of the application (it can be omitted only if there is a single application running)'
|
|
133
|
-
},
|
|
134
154
|
{
|
|
135
155
|
name: 'application',
|
|
136
156
|
description: 'The application ID to profile (if omitted, profiles all applications)'
|
|
137
157
|
}
|
|
138
158
|
],
|
|
139
159
|
footer:
|
|
140
|
-
'Use "pprof start [application]" to start profiling and "pprof stop [application]" to stop and save profile data
|
|
160
|
+
'Use "pprof start [application]" to start profiling and "pprof stop [application]" to stop and save profile data.\n' +
|
|
161
|
+
'Examples:\n' +
|
|
162
|
+
' wattpm pprof start --type=cpu my-app # Start CPU profiling\n' +
|
|
163
|
+
' wattpm pprof start --type=heap my-app # Start heap profiling\n' +
|
|
164
|
+
' wattpm pprof stop --type=cpu my-app # Stop CPU profiling\n' +
|
|
165
|
+
' wattpm pprof stop --type=heap my-app # Stop heap profiling'
|
|
141
166
|
}
|
|
142
167
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wattpm",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "The Node.js Application Server",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"pino-pretty": "^13.0.0",
|
|
30
30
|
"split2": "^4.2.0",
|
|
31
31
|
"table": "^6.8.2",
|
|
32
|
-
"@platformatic/foundation": "3.
|
|
33
|
-
"@platformatic/runtime": "3.
|
|
34
|
-
"@platformatic/control": "3.
|
|
32
|
+
"@platformatic/foundation": "3.9.0",
|
|
33
|
+
"@platformatic/runtime": "3.9.0",
|
|
34
|
+
"@platformatic/control": "3.9.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"cleaner-spec-reporter": "^0.5.0",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"neostandard": "^0.12.0",
|
|
43
43
|
"typescript": "^5.5.4",
|
|
44
44
|
"undici": "^7.0.0",
|
|
45
|
-
"@platformatic/node": "3.
|
|
45
|
+
"@platformatic/node": "3.9.0"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=22.19.0"
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/wattpm/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/wattpm/3.9.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Runtime Config",
|
|
5
5
|
"type": "object",
|
|
@@ -923,8 +923,7 @@
|
|
|
923
923
|
{
|
|
924
924
|
"type": "string"
|
|
925
925
|
}
|
|
926
|
-
]
|
|
927
|
-
"default": 1
|
|
926
|
+
]
|
|
928
927
|
},
|
|
929
928
|
"workersRestartDelay": {
|
|
930
929
|
"anyOf": [
|
|
@@ -1828,6 +1827,72 @@
|
|
|
1828
1827
|
],
|
|
1829
1828
|
"additionalProperties": false
|
|
1830
1829
|
},
|
|
1830
|
+
"verticalScaler": {
|
|
1831
|
+
"type": "object",
|
|
1832
|
+
"properties": {
|
|
1833
|
+
"enabled": {
|
|
1834
|
+
"type": "boolean",
|
|
1835
|
+
"default": true
|
|
1836
|
+
},
|
|
1837
|
+
"maxTotalWorkers": {
|
|
1838
|
+
"type": "number",
|
|
1839
|
+
"minimum": 1
|
|
1840
|
+
},
|
|
1841
|
+
"minWorkers": {
|
|
1842
|
+
"type": "number",
|
|
1843
|
+
"minimum": 1
|
|
1844
|
+
},
|
|
1845
|
+
"maxWorkers": {
|
|
1846
|
+
"type": "number",
|
|
1847
|
+
"minimum": 1
|
|
1848
|
+
},
|
|
1849
|
+
"scaleUpELU": {
|
|
1850
|
+
"type": "number",
|
|
1851
|
+
"minimum": 0,
|
|
1852
|
+
"maximum": 1
|
|
1853
|
+
},
|
|
1854
|
+
"scaleDownELU": {
|
|
1855
|
+
"type": "number",
|
|
1856
|
+
"minimum": 0,
|
|
1857
|
+
"maximum": 1
|
|
1858
|
+
},
|
|
1859
|
+
"minELUDiff": {
|
|
1860
|
+
"type": "number",
|
|
1861
|
+
"minimum": 0,
|
|
1862
|
+
"maximum": 1
|
|
1863
|
+
},
|
|
1864
|
+
"timeWindowSec": {
|
|
1865
|
+
"type": "number",
|
|
1866
|
+
"minimum": 0
|
|
1867
|
+
},
|
|
1868
|
+
"cooldownSec": {
|
|
1869
|
+
"type": "number",
|
|
1870
|
+
"minimum": 0
|
|
1871
|
+
},
|
|
1872
|
+
"scaleIntervalSec": {
|
|
1873
|
+
"type": "number",
|
|
1874
|
+
"minimum": 0
|
|
1875
|
+
},
|
|
1876
|
+
"applications": {
|
|
1877
|
+
"type": "object",
|
|
1878
|
+
"additionalProperties": {
|
|
1879
|
+
"type": "object",
|
|
1880
|
+
"properties": {
|
|
1881
|
+
"minWorkers": {
|
|
1882
|
+
"type": "number",
|
|
1883
|
+
"minimum": 1
|
|
1884
|
+
},
|
|
1885
|
+
"maxWorkers": {
|
|
1886
|
+
"type": "number",
|
|
1887
|
+
"minimum": 1
|
|
1888
|
+
}
|
|
1889
|
+
},
|
|
1890
|
+
"additionalProperties": false
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
},
|
|
1894
|
+
"additionalProperties": false
|
|
1895
|
+
},
|
|
1831
1896
|
"inspectorOptions": {
|
|
1832
1897
|
"type": "object",
|
|
1833
1898
|
"properties": {
|