github.com/emate/nomad@v0.8.2-wo-binpacking/ui/app/utils/classes/log.js (about)

     1  import Ember from 'ember';
     2  import { alias } from '@ember/object/computed';
     3  import { assert } from '@ember/debug';
     4  import Evented from '@ember/object/evented';
     5  import EmberObject, { computed } from '@ember/object';
     6  import { assign } from '@ember/polyfills';
     7  import queryString from 'npm:query-string';
     8  import { task } from 'ember-concurrency';
     9  import StreamLogger from 'nomad-ui/utils/classes/stream-logger';
    10  import PollLogger from 'nomad-ui/utils/classes/poll-logger';
    11  
    12  const MAX_OUTPUT_LENGTH = 50000;
    13  
    14  export const fetchFailure = url => () => Ember.Logger.warn(`LOG FETCH: Couldn't connect to ${url}`);
    15  
    16  const Log = EmberObject.extend(Evented, {
    17    // Parameters
    18  
    19    url: '',
    20    params: computed(() => ({})),
    21    logFetch() {
    22      assert('Log objects need a logFetch method, which should have an interface like window.fetch');
    23    },
    24  
    25    // Read-only state
    26  
    27    isStreaming: alias('logStreamer.poll.isRunning'),
    28    logPointer: null,
    29    logStreamer: null,
    30  
    31    // The top of the log
    32    head: '',
    33  
    34    // The bottom of the log
    35    tail: '',
    36  
    37    // The top or bottom of the log, depending on whether
    38    // the logPointer is pointed at head or tail
    39    output: computed('logPointer', 'head', 'tail', function() {
    40      return this.get('logPointer') === 'head' ? this.get('head') : this.get('tail');
    41    }),
    42  
    43    init() {
    44      this._super();
    45  
    46      const args = this.getProperties('url', 'params', 'logFetch');
    47      args.write = chunk => {
    48        let newTail = this.get('tail') + chunk;
    49        if (newTail.length > MAX_OUTPUT_LENGTH) {
    50          newTail = newTail.substr(newTail.length - MAX_OUTPUT_LENGTH);
    51        }
    52        this.set('tail', newTail);
    53        this.trigger('tick', chunk);
    54      };
    55  
    56      if (StreamLogger.isSupported) {
    57        this.set('logStreamer', StreamLogger.create(args));
    58      } else {
    59        this.set('logStreamer', PollLogger.create(args));
    60      }
    61    },
    62  
    63    destroy() {
    64      this.stop();
    65      this._super();
    66    },
    67  
    68    gotoHead: task(function*() {
    69      const logFetch = this.get('logFetch');
    70      const queryParams = queryString.stringify(
    71        assign(this.get('params'), {
    72          plain: true,
    73          origin: 'start',
    74          offset: 0,
    75        })
    76      );
    77      const url = `${this.get('url')}?${queryParams}`;
    78  
    79      this.stop();
    80      let text = yield logFetch(url).then(res => res.text(), fetchFailure(url));
    81  
    82      if (text && text.length > MAX_OUTPUT_LENGTH) {
    83        text = text.substr(0, MAX_OUTPUT_LENGTH);
    84        text += '\n\n---------- TRUNCATED: Click "tail" to view the bottom of the log ----------';
    85      }
    86      this.set('head', text);
    87      this.set('logPointer', 'head');
    88    }),
    89  
    90    gotoTail: task(function*() {
    91      const logFetch = this.get('logFetch');
    92      const queryParams = queryString.stringify(
    93        assign(this.get('params'), {
    94          plain: true,
    95          origin: 'end',
    96          offset: MAX_OUTPUT_LENGTH,
    97        })
    98      );
    99      const url = `${this.get('url')}?${queryParams}`;
   100  
   101      this.stop();
   102      let text = yield logFetch(url).then(res => res.text(), fetchFailure(url));
   103  
   104      this.set('tail', text);
   105      this.set('logPointer', 'tail');
   106    }),
   107  
   108    startStreaming() {
   109      this.set('logPointer', 'tail');
   110      return this.get('logStreamer').start();
   111    },
   112  
   113    stop() {
   114      this.get('logStreamer').stop();
   115    },
   116  });
   117  
   118  export default Log;
   119  
   120  export function logger(urlProp, params, logFetch) {
   121    return computed(urlProp, params, function() {
   122      return Log.create({
   123        logFetch: logFetch.call(this),
   124        params: this.get(params),
   125        url: this.get(urlProp),
   126      });
   127    });
   128  }