All files / lib/services diagnostics.service.ts

88% Statements 22/25
75% Branches 3/4
88.88% Functions 8/9
91.3% Lines 21/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                3x   3x     3x 5x 5x       2x 2x 2x 1x 1x   2x 2x       2x 2x 2x     2x       1x           2x     2x                                                                     1x 1x                        
import { Inject, Injectable, Logger } from '@nestjs/common';
import { exec, ExecException } from 'child_process';
import * as dotenv from 'dotenv';
import * as os from 'os';
import { catchError, map, Observable, of } from 'rxjs';
 
import { IDiagnosticsService, IPingResult, TDiagData } from '../interfaces/diagnostics.interface';
 
export const CHILD_PROCESS_EXEC = Symbol('CHILD_PROCESS_EXEC');
 
export const DIAGNOSTICS_SERVICE_TOKEN = Symbol('DIAGNOSTICS_SERVICE_TOKEN');
 
@Injectable()
export class AppDiagnosticsService implements IDiagnosticsService {
  constructor(@Inject(CHILD_PROCESS_EXEC) private readonly childProcessExec: typeof exec) {
    dotenv.config();
  }
 
  private npmVersion() {
    const observable$ = new Observable<string>(subscriber => {
      let version = 'N/A';
      if (typeof process.env['ELECTRON'] !== 'undefined') {
        subscriber.next(version);
        subscriber.complete();
      }
      this.childProcessExec('npm --version', (error: ExecException | null, stdout: string, stderr: string) => {
        Iif (error !== null) {
          Logger.error(error);
          subscriber.error(version);
        }
        version = stdout.toString().replace(os.EOL, '');
        subscriber.next(version);
        subscriber.complete();
      });
    });
    return observable$.pipe(catchError((error: string) => of(error)));
  }
 
  public ping(): IPingResult {
    return {
      message: 'Diagnostics service is online. Routes: /, /static.',
    } as IPingResult;
  }
 
  public static(): Observable<TDiagData> {
    return this.npmVersion().pipe(
      map(
        npmVersion =>
          [
            {
              name: 'Node.js Version',
              value: process.version.replace('v', ''),
            },
            {
              name: 'NPM Version',
              value: npmVersion,
            },
            {
              name: 'OS Type',
              value: os.type(),
            },
            {
              name: 'OS Platform',
              value: os.platform(),
            },
            {
              name: 'OS Architecture',
              value: os.arch(),
            },
            {
              name: 'OS Release',
              value: os.release(),
            },
            {
              name: 'CPU Cores',
              value: os.cpus().length,
            },
          ] as TDiagData,
      ),
    );
  }
 
  public dynamic(): TDiagData {
    const divider = 1048576;
    return [
      {
        name: 'Free Memory',
        value: `${Math.round(os.freemem() / divider)}MB`,
      },
      {
        name: 'Uptime',
        value: `${os.uptime()}s`,
      },
    ] as TDiagData;
  }
}