wattpm 3.41.0 → 3.43.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/README.md +4 -3
- package/index.js +4 -0
- package/lib/commands/help.js +2 -1
- package/lib/commands/pprof.js +4 -4
- package/lib/commands/snapshot.js +99 -0
- package/package.json +5 -5
- package/schema.json +4 -1
package/README.md
CHANGED
|
@@ -19,18 +19,19 @@ Watt supports the stacks you love most, including [Next.js](https://nextjs.org/)
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
# Create a new application
|
|
22
|
-
npx wattpm@latest
|
|
22
|
+
npx wattpm@latest create
|
|
23
23
|
|
|
24
24
|
# Or install manually:
|
|
25
25
|
npm install wattpm
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Follow our [Quick Start Guide](https://docs.platformatic.dev/docs/getting-started/quick-start)
|
|
29
|
-
|
|
29
|
+
to get up and running with Watt.
|
|
30
30
|
|
|
31
31
|
## Documentation
|
|
32
32
|
|
|
33
|
-
- [
|
|
33
|
+
- [Quick Start](https://docs.platformatic.dev/docs/getting-started/quick-start)
|
|
34
|
+
- [Running Your Project in Watt](https://docs.platformatic.dev/docs/getting-started/port-your-app)
|
|
34
35
|
- [Reference](https://docs.platformatic.dev/docs/reference/wattpm/overview)
|
|
35
36
|
- [Guides](https://docs.platformatic.dev/docs/guides/build-modular-monolith)
|
|
36
37
|
|
package/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { applicationsCommand, configCommand, envCommand, psCommand } from './lib
|
|
|
14
14
|
import { metricsCommand } from './lib/commands/metrics.js'
|
|
15
15
|
import { pprofCommand } from './lib/commands/pprof.js'
|
|
16
16
|
import { replCommand } from './lib/commands/repl.js'
|
|
17
|
+
import { heapSnapshotCommand } from './lib/commands/snapshot.js'
|
|
17
18
|
import { version } from './lib/schema.js'
|
|
18
19
|
|
|
19
20
|
export * from './lib/schema.js'
|
|
@@ -116,6 +117,9 @@ export async function main () {
|
|
|
116
117
|
case 'pprof':
|
|
117
118
|
command = pprofCommand
|
|
118
119
|
break
|
|
120
|
+
case 'heap-snapshot':
|
|
121
|
+
command = heapSnapshotCommand
|
|
122
|
+
break
|
|
119
123
|
case 'repl':
|
|
120
124
|
command = replCommand
|
|
121
125
|
break
|
package/lib/commands/help.js
CHANGED
package/lib/commands/pprof.js
CHANGED
|
@@ -168,20 +168,20 @@ export const help = {
|
|
|
168
168
|
description: 'Profile CPU or heap usage of running application',
|
|
169
169
|
options: [
|
|
170
170
|
{
|
|
171
|
-
|
|
171
|
+
usage: '--type, -t',
|
|
172
172
|
description: 'Profile type: "cpu" for CPU wall time (default) or "heap" for heap memory'
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
|
-
|
|
175
|
+
usage: '--source-maps, -s',
|
|
176
176
|
description: 'Enable source map support to resolve TypeScript and other transpiled code locations in profiles'
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
|
-
|
|
179
|
+
usage: '--node-modules-source-maps, -n',
|
|
180
180
|
description:
|
|
181
181
|
'Comma-separated list of node_modules packages to load source maps from (e.g., "next,@next/next-server")'
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
|
-
|
|
184
|
+
usage: '--dir, -d',
|
|
185
185
|
description:
|
|
186
186
|
'Directory to save the profile data to (default: current working directory). Only used with "stop" subcommand.'
|
|
187
187
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { RuntimeApiClient, getMatchingRuntime } from '@platformatic/control'
|
|
2
|
+
import { ensureLoggableError, logFatalError, parseArgs } from '@platformatic/foundation'
|
|
3
|
+
import { bold } from 'colorette'
|
|
4
|
+
import { createWriteStream } from 'node:fs'
|
|
5
|
+
import { resolve } from 'node:path'
|
|
6
|
+
import { pipeline } from 'node:stream/promises'
|
|
7
|
+
|
|
8
|
+
export async function heapSnapshotCommand (logger, args) {
|
|
9
|
+
const client = new RuntimeApiClient({ logger, socket: this.socket })
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const { positionals, values } = parseArgs(
|
|
13
|
+
args,
|
|
14
|
+
{
|
|
15
|
+
dir: { type: 'string', short: 'd' }
|
|
16
|
+
},
|
|
17
|
+
false
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const [runtime, remainingPositionals] = await getMatchingRuntime(client, positionals)
|
|
21
|
+
const { applications: runtimeApplications } = await client.getRuntimeApplications(runtime.pid)
|
|
22
|
+
|
|
23
|
+
const applicationId = remainingPositionals[0]
|
|
24
|
+
const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\./g, '-')
|
|
25
|
+
const outputDir = values.dir || process.cwd()
|
|
26
|
+
|
|
27
|
+
if (applicationId) {
|
|
28
|
+
const application = runtimeApplications.find(s => s.id === applicationId)
|
|
29
|
+
if (!application) {
|
|
30
|
+
return logFatalError(logger, `Application not found: ${applicationId}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
logger.info(`Taking heap snapshot for application ${bold(applicationId)}...`)
|
|
34
|
+
const body = await client.takeApplicationHeapSnapshot(runtime.pid, applicationId)
|
|
35
|
+
const filename = `heap-${applicationId}-${timestamp}.heapsnapshot`
|
|
36
|
+
const filepath = resolve(outputDir, filename)
|
|
37
|
+
await pipeline(body, createWriteStream(filepath))
|
|
38
|
+
logger.info(`Heap snapshot saved to ${bold(filepath)}`)
|
|
39
|
+
} else {
|
|
40
|
+
for (const application of runtimeApplications) {
|
|
41
|
+
try {
|
|
42
|
+
logger.info(`Taking heap snapshot for application ${bold(application.id)}...`)
|
|
43
|
+
const body = await client.takeApplicationHeapSnapshot(runtime.pid, application.id)
|
|
44
|
+
const filename = `heap-${application.id}-${timestamp}.heapsnapshot`
|
|
45
|
+
const filepath = resolve(outputDir, filename)
|
|
46
|
+
await pipeline(body, createWriteStream(filepath))
|
|
47
|
+
logger.info(`Heap snapshot saved to ${bold(filepath)}`)
|
|
48
|
+
} catch (error) {
|
|
49
|
+
logger.warn(`Failed to take heap snapshot for application ${application.id}: ${error.message}`)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (error.code === 'PLT_CTR_RUNTIME_NOT_FOUND') {
|
|
55
|
+
return logFatalError(logger, 'Cannot find a matching runtime.')
|
|
56
|
+
} else if (error.message && error.message.includes('Application not found')) {
|
|
57
|
+
return logFatalError(logger, error.message)
|
|
58
|
+
} else {
|
|
59
|
+
return logFatalError(
|
|
60
|
+
logger,
|
|
61
|
+
{ error: ensureLoggableError(error) },
|
|
62
|
+
`Cannot take heap snapshot: ${error.message}`
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
} finally {
|
|
66
|
+
await client.close()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const help = {
|
|
71
|
+
'heap-snapshot': {
|
|
72
|
+
usage: 'heap-snapshot [id] [application] [options]',
|
|
73
|
+
description: 'Take a heap snapshot of a running application',
|
|
74
|
+
options: [
|
|
75
|
+
{
|
|
76
|
+
usage: '--dir, -d',
|
|
77
|
+
description: 'Directory to save the heap snapshot to (default: current working directory)'
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
args: [
|
|
81
|
+
{
|
|
82
|
+
name: 'id',
|
|
83
|
+
description:
|
|
84
|
+
'The process ID or the name of the application (it can be omitted only if there is a single application running)'
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'application',
|
|
88
|
+
description: 'The application ID to snapshot (if omitted, snapshots all applications)'
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
footer:
|
|
92
|
+
'Takes a V8 heap snapshot of a running application and saves it as a .heapsnapshot file.\n' +
|
|
93
|
+
'The resulting file can be loaded in Chrome DevTools (Memory tab) for analysis.\n\n' +
|
|
94
|
+
'Examples:\n' +
|
|
95
|
+
' wattpm heap-snapshot my-app # Take heap snapshot of my-app\n' +
|
|
96
|
+
' wattpm heap-snapshot --dir=/tmp/snapshots my-app # Save to specific directory\n' +
|
|
97
|
+
' wattpm heap-snapshot # Snapshot all applications'
|
|
98
|
+
}
|
|
99
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wattpm",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.43.0",
|
|
4
4
|
"description": "The Node.js Application Server",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"pino-pretty": "^13.0.0",
|
|
31
31
|
"split2": "^4.2.0",
|
|
32
32
|
"table": "^6.8.2",
|
|
33
|
-
"@platformatic/foundation": "3.
|
|
34
|
-
"@platformatic/
|
|
35
|
-
"@platformatic/
|
|
33
|
+
"@platformatic/foundation": "3.43.0",
|
|
34
|
+
"@platformatic/control": "3.43.0",
|
|
35
|
+
"@platformatic/runtime": "3.43.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"cleaner-spec-reporter": "^0.5.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"neostandard": "^0.12.0",
|
|
45
45
|
"typescript": "^5.5.4",
|
|
46
46
|
"undici": "^7.0.0",
|
|
47
|
-
"@platformatic/node": "3.
|
|
47
|
+
"@platformatic/node": "3.43.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"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.43.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Runtime Config",
|
|
5
5
|
"type": "object",
|
|
@@ -2751,6 +2751,9 @@
|
|
|
2751
2751
|
"type": "string"
|
|
2752
2752
|
}
|
|
2753
2753
|
},
|
|
2754
|
+
"envfile": {
|
|
2755
|
+
"type": "string"
|
|
2756
|
+
},
|
|
2754
2757
|
"sourceMaps": {
|
|
2755
2758
|
"type": "boolean",
|
|
2756
2759
|
"default": false
|