1
1
var common = require ( '../../../api/utils/common.js' ) ;
2
2
const inspector = require ( 'inspector' ) ;
3
- const countlyFs = require ( '../../../api/utils/countlyFs.js' ) ;
4
3
var exec = require ( 'child_process' ) . exec ;
5
4
const tar = require ( "tar-stream" ) ;
6
5
const session = new inspector . Session ( ) ;
6
+ const path = require ( "path" ) ;
7
+ const fs = require ( "fs/promises" ) ;
8
+ const { Writable } = require ( 'stream' ) ;
7
9
8
- const PROFILER_DIR = " nodeprofile";
10
+ const PROFILER_DIR = path . join ( __dirname , "../../../log/ nodeprofile") ;
9
11
10
12
var _id = null ;
11
13
@@ -424,23 +426,20 @@ function sessionPost(cmd) {
424
426
}
425
427
426
428
/**
427
- * Saves the result to gridfs
428
- * @param { string } filename file name with extension
429
- * @param {object } result result object returned by the profiler
430
- * @returns {Promise<string> } filename
429
+ * Takes a snapshot and writes its content to the passed stream.
430
+ * IMPORTANT: it will call the "end" for the passed stream object when it's done
431
+ * @param {Writable } stream Writable stream to write snapshot content to
432
+ * @returns {void }
431
433
*/
432
- function saveProfilerResult ( filename , result ) {
433
- return new Promise ( ( res , rej ) => {
434
- countlyFs . gridfs . saveData (
435
- PROFILER_DIR , filename , JSON . stringify ( result ) ,
436
- { writeMode : "overwrite" } ,
437
- function ( err ) {
438
- if ( err ) {
439
- return rej ( err ) ;
440
- }
441
- res ( filename ) ;
442
- }
443
- ) ;
434
+ function takeHeapSnapshot ( stream ) {
435
+ session . connect ( ) ;
436
+ session . on ( "HeapProfiler.addHeapSnapshotChunk" , m => stream . write ( m . params . chunk ) ) ;
437
+ session . post ( "HeapProfiler.takeHeapSnapshot" , null , ( err ) => {
438
+ session . disconnect ( ) ;
439
+ stream . end ( ) ;
440
+ if ( err ) {
441
+ console . error ( err ) ;
442
+ }
444
443
} ) ;
445
444
}
446
445
@@ -470,30 +469,22 @@ async function startProfiler() {
470
469
async function stopProfiler ( processName ) {
471
470
const errors = [ ] ;
472
471
473
- // clear old files
474
472
try {
475
- await new Promise (
476
- ( res , rej ) => countlyFs . gridfs . deleteAll (
477
- PROFILER_DIR ,
478
- null ,
479
- err => err ? rej ( err ) : res ( )
480
- )
481
- ) ;
473
+ await fs . rm ( PROFILER_DIR , { force : true , recursive : true } ) ; // clear old files
474
+ await fs . mkdir ( PROFILER_DIR , { recursive : true } ) ;
482
475
}
483
476
catch ( err ) {
484
- if ( err . code === 26 ) { // NamespaceNotFound: thrown when there's no collection initially
485
- // do nothing...
486
- }
487
- else {
488
- throw err ;
489
- }
477
+ errors . push ( err ) ;
490
478
}
491
479
492
480
// coverage
493
481
try {
494
482
const coverage = await sessionPost ( "Profiler.takePreciseCoverage" ) ;
495
- await saveProfilerResult ( processName + ".coverage" , coverage ?. result ) ;
496
483
await sessionPost ( "Profiler.stopPreciseCoverage" ) ;
484
+ await fs . writeFile (
485
+ path . join ( PROFILER_DIR , processName + ".coverage" ) ,
486
+ JSON . stringify ( coverage ?. result )
487
+ ) ;
497
488
}
498
489
catch ( err ) {
499
490
errors . push ( err ) ;
@@ -502,8 +493,11 @@ async function stopProfiler(processName) {
502
493
// cpu profiler
503
494
try {
504
495
const cpuProfile = await sessionPost ( "Profiler.stop" ) ;
505
- await saveProfilerResult ( processName + ".cpuprofile" , cpuProfile ?. profile ) ;
506
496
await sessionPost ( "Profiler.disable" ) ;
497
+ await fs . writeFile (
498
+ path . join ( PROFILER_DIR , processName + ".cpuprofile" ) ,
499
+ JSON . stringify ( cpuProfile ?. profile )
500
+ ) ;
507
501
}
508
502
catch ( err ) {
509
503
errors . push ( err ) ;
@@ -512,8 +506,11 @@ async function stopProfiler(processName) {
512
506
// heap profiler
513
507
try {
514
508
const heapProfile = await sessionPost ( "HeapProfiler.stopSampling" ) ;
515
- await saveProfilerResult ( processName + ".heapprofile" , heapProfile ?. profile ) ;
516
509
await sessionPost ( "HeapProfiler.disable" ) ;
510
+ await fs . writeFile (
511
+ path . join ( PROFILER_DIR , processName + ".heapprofile" ) ,
512
+ JSON . stringify ( heapProfile ?. profile )
513
+ ) ;
517
514
}
518
515
catch ( err ) {
519
516
errors . push ( err ) ;
@@ -526,39 +523,24 @@ async function stopProfiler(processName) {
526
523
}
527
524
}
528
525
529
- /**
530
- * Returns the data of a file in PROFILER_DIR collection
531
- * @param {string } filename file name with extension
532
- * @returns {Promise<{data:string, filename:string}> } file object with name and content
533
- */
534
- function downloadProfilerFile ( filename ) {
535
- return new Promise ( ( resolve , reject ) => {
536
- countlyFs . gridfs . getData ( PROFILER_DIR , filename , { } , ( err , data ) => {
537
- if ( err ) {
538
- return reject ( "File not found" ) ;
539
- }
540
- resolve ( { data, filename } ) ;
541
- } ) ;
542
- } ) ;
543
- }
544
526
/**
545
527
* Returns the names, creation dates and size of all files in the PROFILER_DIR collection
546
- * @returns {Promise<Array<{createdOn: Date, filename: string, size: number }>> } file info
528
+ * @returns {Promise<Array<{createdOn: Date, filename: string, size: number, path: string }>> } file info
547
529
*/
548
- function listProfilerFiles ( ) {
549
- return new Promise ( ( resolve , reject ) => {
550
- countlyFs . gridfs . listFiles ( PROFILER_DIR , ( err , files ) => {
551
- if ( err ) {
552
- return reject ( err ) ;
553
- }
554
- resolve ( files ) ;
555
- } ) ;
556
- } ) ;
530
+ async function listProfilerFiles ( ) {
531
+ const files = await fs . readdir ( PROFILER_DIR ) ;
532
+ return Promise . all (
533
+ files . map ( async ( filename ) => {
534
+ const fullPath = path . join ( PROFILER_DIR , filename ) ;
535
+ const { birthtime , size } = await fs . stat ( fullPath ) ;
536
+ return { createdOn : birthtime , size , filename , path : fullPath }
537
+ } )
538
+ ) ;
557
539
}
558
540
559
541
/**
560
542
* Returns the tarball read stream for all profiler files
561
- * @returns {tar.Pack } tar stream
543
+ * @returns {Promise< tar.Pack> } tar stream
562
544
*/
563
545
async function profilerFilesTarStream ( ) {
564
546
const files = await listProfilerFiles ( ) ;
@@ -569,14 +551,8 @@ async function profilerFilesTarStream() {
569
551
const pack = tar . pack ( ) ;
570
552
for ( let i = 0 ; i < files . length ; i ++ ) {
571
553
const entry = pack . entry ( { name : files [ i ] . filename , size : files [ i ] . size } ) ;
572
- const stream = await new Promise ( ( res , rej ) => {
573
- countlyFs . gridfs . getStream (
574
- PROFILER_DIR ,
575
- files [ i ] . filename ,
576
- { } ,
577
- ( err , fileStream ) => err ? rej ( err ) : res ( fileStream )
578
- ) ;
579
- } ) ;
554
+ const handle = await fs . open ( files [ i ] . path ) ;
555
+ const stream = handle . createReadStream ( ) ;
580
556
stream . pipe ( entry ) ;
581
557
stream . on ( "end" , ( ) => {
582
558
entry . end ( ) ;
@@ -622,9 +598,9 @@ function stopInspector() {
622
598
} ) ;
623
599
}
624
600
601
+ exports . takeHeapSnapshot = takeHeapSnapshot ;
625
602
exports . startProfiler = startProfiler ;
626
603
exports . stopProfiler = stopProfiler ;
627
- exports . downloadProfilerFile = downloadProfilerFile ;
628
604
exports . listProfilerFiles = listProfilerFiles ;
629
605
exports . startInspector = startInspector ;
630
606
exports . stopInspector = stopInspector ;
0 commit comments