File size: 2,463 Bytes
4327358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import * as v8 from 'node:v8';

import {
  Controller,
  Get,
  Logger,
  NotFoundException,
  Query,
  StreamableFile,
  UsePipes,
} from '@nestjs/common';
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
import { WhatsappConfigService } from '@waha/config.service';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { WhatsappSession } from '@waha/core/abc/session.abc';
import {
  SessionApiParam,
  WorkingSessionParam,
} from '@waha/nestjs/params/SessionApiParam';
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
import { BrowserTraceQuery } from '@waha/structures/server.debug.dto';
import { createReadStream } from 'fs';

@ApiSecurity('api_key')
@Controller('api/server/debug')
@ApiTags('🔍 Observability')
export class ServerDebugController {
  private logger: Logger;
  private readonly enabled: boolean;

  constructor(
    private config: WhatsappConfigService,
    private manager: SessionManager,
  ) {
    this.logger = new Logger('ServerDebugController');
    this.enabled = this.config.debugModeEnabled;
  }

  @Get('heapsnapshot')
  @ApiOperation({
    summary: 'Return a heapsnapshot for the current nodejs process',
    description: "Return a heapsnapshot of the server's memory",
  })
  async heapsnapshot() {
    if (!this.enabled) {
      throw new NotFoundException('WAHA_DEBUG_MODE is disabled');
    }
    this.logger.log('Creating a heap snapshot...');
    const heap = v8.getHeapSnapshot();
    const fileName = `${Date.now()}.heapsnapshot`;
    return new StreamableFile(heap, {
      type: 'application/octet-stream',
      disposition: `attachment; filename=${fileName}`,
    });
  }

  @Get('browser/trace/:session')
  @ApiOperation({
    summary: 'Collect and get a trace.json for Chrome DevTools ',
    description: 'Uses https://pptr.dev/api/puppeteer.tracing',
  })
  @SessionApiParam
  @UsePipes(new WAHAValidationPipe())
  async browserTrace(
    @WorkingSessionParam session: WhatsappSession,
    @Query() query: BrowserTraceQuery,
  ) {
    if (!this.enabled) {
      throw new NotFoundException('WAHA_DEBUG_MODE is disabled');
    }
    const filepath = await session.browserTrace(query);
    const stream = createReadStream(filepath);
    const filename = `trace - ${session.name} - ${new Date()}.json`;
    return new StreamableFile(stream, {
      type: 'application/octet-stream',
      disposition: `attachment; filename=${filename}`,
    });
  }
}