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 }