github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/components/task-log.js (about)

     1  import { inject as service } from '@ember/service';
     2  import Component from '@ember/component';
     3  import { action, computed } from '@ember/object';
     4  import { alias } from '@ember/object/computed';
     5  import RSVP from 'rsvp';
     6  import { logger } from 'nomad-ui/utils/classes/log';
     7  import timeout from 'nomad-ui/utils/timeout';
     8  import { classNames } from '@ember-decorators/component';
     9  import classic from 'ember-classic-decorator';
    10  
    11  class MockAbortController {
    12    abort() {
    13      /* noop */
    14    }
    15  }
    16  
    17  @classic
    18  @classNames('boxed-section', 'task-log')
    19  export default class TaskLog extends Component {
    20    @service token;
    21    @service userSettings;
    22  
    23    allocation = null;
    24    task = null;
    25  
    26    // When true, request logs from the server agent
    27    useServer = false;
    28  
    29    // When true, logs cannot be fetched from either the client or the server
    30    noConnection = false;
    31  
    32    clientTimeout = 1000;
    33    serverTimeout = 5000;
    34  
    35    isStreaming = true;
    36    streamMode = 'streaming';
    37  
    38    shouldFillHeight = true;
    39  
    40    @alias('userSettings.logMode') mode;
    41  
    42    @computed('allocation.{id,node.httpAddr}', 'useServer')
    43    get logUrl() {
    44      const address = this.get('allocation.node.httpAddr');
    45      const allocation = this.get('allocation.id');
    46  
    47      const url = `/v1/client/fs/logs/${allocation}`;
    48      return this.useServer ? url : `//${address}${url}`;
    49    }
    50  
    51    @computed('task', 'mode')
    52    get logParams() {
    53      return {
    54        task: this.task,
    55        type: this.mode,
    56      };
    57    }
    58  
    59    @logger('logUrl', 'logParams', function logFetch() {
    60      // If the log request can't settle in one second, the client
    61      // must be unavailable and the server should be used instead
    62  
    63      const aborter = window.AbortController
    64        ? new AbortController()
    65        : new MockAbortController();
    66      const timing = this.useServer ? this.serverTimeout : this.clientTimeout;
    67  
    68      // Capture the state of useServer at logger create time to avoid a race
    69      // between the stdout logger and stderr logger running at once.
    70      const useServer = this.useServer;
    71      return (url) =>
    72        RSVP.race([
    73          this.token.authorizedRequest(url, { signal: aborter.signal }),
    74          timeout(timing),
    75        ]).then(
    76          (response) => {
    77            return response;
    78          },
    79          (error) => {
    80            aborter.abort();
    81            if (useServer) {
    82              this.set('noConnection', true);
    83            } else {
    84              this.send('failoverToServer');
    85            }
    86            throw error;
    87          }
    88        );
    89    })
    90    logger;
    91  
    92    @action
    93    setMode(mode) {
    94      if (this.mode === mode) return;
    95      this.logger.stop();
    96      this.set('mode', mode);
    97    }
    98  
    99    @action
   100    toggleStream() {
   101      this.set('streamMode', 'streaming');
   102      this.toggleProperty('isStreaming');
   103    }
   104  
   105    @action
   106    gotoHead() {
   107      this.set('streamMode', 'head');
   108      this.set('isStreaming', false);
   109    }
   110  
   111    @action
   112    gotoTail() {
   113      this.set('streamMode', 'tail');
   114      this.set('isStreaming', false);
   115    }
   116  
   117    @action
   118    failoverToServer() {
   119      this.set('useServer', true);
   120    }
   121  }