HelloCSE/public/js/logsreader.js
2024-04-10 13:56:22 +02:00

346 lignes
Pas d'EOL
14 Kio
JavaScript

new Vue({
el:'#logsreader',
created(){
let params=this.getUrlParam(window.location.href);
this.token=params.token
this.userId=params.iduser
this.bridge=`${this.getURL()}/logsreader`;
this.getKeyList();
},
data:{
bridge:'',
token:'',
userId:'',
logsKeys:[],
logs:{},
menuActiveKey:'',
activeLog:'',
activeLogKey:'',
error:false,
menuOpen:false,
},
computed:{
loadedLogs(){
let logs=[];
_.forEach(this.logs,(logCollection,logCollectionKey)=>{
_.forEach(logCollection.files,(value,logKey)=>{
logs.push({
logCollectionKey:logCollectionKey,
fileName:logKey.replace(logCollectionKey+'_',''),
logKey:logKey,
content:value.content,
active:value.active
});
});
});
return logs;
}
},
watch:{
menuActiveKey:function(newVal,old){
if(newVal.length && newVal!==old && !this.logs[this.menuActiveKey].filesNames.length)
this.getLogsList();
}
},
template: `
<div @click="menuOpen=false" id="main">
<div class="errormsg" v-if="error" @click="error=false">{{error}}</div>
<header>
<menu>
<div @click.stop="menuOpen=!menuOpen" class="ico">&#9776;</div>
<div v-if="menuOpen" class="handler">
<div class="keylist">
<div class="mainkl">
<div v-if="_.isEmpty(logsKeys)">Chargement...</div>
<div v-else
@click.stop="menuActiveKey=key"
:class="['logkey',{'active':key===menuActiveKey}]"
v-for="(nb,key) in logsKeys"
:key="'link'+key"
>
{{key.toLowerCase()}} ({{nb}})
</div>
</div>
<div v-if="menuActiveKey" class="secondkl">
<div
@click="checkOutLog(menuActiveKey,fileName)"
class="filename"
v-for="fileName in logs[menuActiveKey].filesNames"
:key="menuActiveKey+'_'+fileName">{{fileName}}
</div>
</div>
</div>
<div @click.stop="reloadLogList()" class="reloadkeylist">Actualiser</div>
</div>
</menu>
<div class="logo">LOGS READER</div>
</header>
<section>
<div class="tabsbtn">
<div
v-for="log in loadedLogs"
@click="showLog(log.logCollectionKey,log.fileName)"
:class="['tabbtn',{'active':activeLog===log.logKey}]"
:key="'tab'+log.logKey"
:title="log.logKey"
>
<div class="tb_refico" v-if="logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].isRefreshing">🔄</div>
<div class="tb_name">{{log.logKey}}</div>
<div @click.stop="closeLog(log.logCollectionKey,log.fileName)" class="tb_close">X</div>
</div>
</div>
<div class="displayer">
<div
v-for="log in loadedLogs" :key="'tab'+log.logKey"
:class="['logdisp',{'active':activeLog===log.logKey}]"
>
<div class="ld_header">
<div>
<div class="ld_refbtn" @click="download(log.logCollectionKey,log.fileName)">💾 Télécharger le log</div>
<div><span title="taille de l'extrait">{{convertSizeWithUnit(logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].extractSize)}}</span>/<span title="taille totale du log">{{convertSizeWithUnit(logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].size)}}</span></div>
</div>
<div>
<div @click="refresh(log.logCollectionKey,log.fileName)" class="ld_refbtn">Actualiser</div>
<div class="ld_autref">
<input
:id="log.logKey+'_autorfcb'"
@change="autoRefresh(log.logCollectionKey,log.fileName)"
type="checkbox"
v-model="logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].autoRefresh"
>
<label :for="log.logKey+'_autorfcb'">Auto Refresh</label>
<input
type="text"
v-model="logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].refreshTimer"
:readonly="logs[log.logCollectionKey].files[log.logCollectionKey+'_'+log.fileName].autoRefresh?'readonly':false"
>
</div>
</div>
</div>
<div class="ld_cont" v-html="log.content" @mouseup="onMouseUp"></div>
</div>
</div>
</section>
</div>
`,
methods:{
// copier depuis la sélection, shell-cmd like
onMouseUp(){
// A ACTIVER QUAND ON SERA EN HTTPS
// let sel=document.getSelection().toString()
// navigator.clipboard.writeText(sel)
return
},
download(key,fileName){
window.open(this.bridge+`/dllog?key=${key}&logName=${fileName}&iduser=${this.userId}&token=${this.token}`);
},
convertSizeWithUnit(size){
let s=parseInt(size);
let unit='o';
if(s>=1000000){
s/=1000000
unit='Mo'
}
else if(s>=1000){
s/=1000
unit='ko'
}
return s+unit;
},
reloadLogList(){
_.forEach(this.logs,(logCollection,logCollectionKey)=>{
_.forEach(logCollection.files,(value,logKey)=>{
this.closeLog(logCollectionKey,logKey.replace(logCollectionKey+'_',''));
});
});
this.activeLog=''
this.activeLogKey=''
this.menuActiveKey=''
this.getKeyList();
},
getUrlParam(url){
return _.chain(url).split('?').nth(1).split('&').map(_.partial(_.split, _, '=', 2)).fromPairs().value()
},
getKeyList(){
this.ajax(this.bridge+'/keyslist')
.then((rep)=>{
if(rep.status){
this.logsKeys=rep.logskeys
for(let key in this.logsKeys){
this.$set(this.logs,key,{filesNames:[],files:{}})
}
return
}
this.error=rep.msg
})
.catch((err)=>{
this.error='erreur AJAX : '+err
})
},
getLogsList(){
this.ajax(this.bridge+'/logslist',{
data:{
key:this.menuActiveKey
}
})
.then((rep)=>{
if(rep.status){
this.$set(this.logs[this.menuActiveKey],'filesNames',rep.logs);
return
}
this.error=rep.msg
})
.catch((err)=>{
this.error='erreur AJAX : '+err
})
},
checkOutLog(logCollectionKey,fileName){
if(!this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`]){
this.getALog(logCollectionKey,fileName).then(()=>{
this.showLog(logCollectionKey,fileName)
})
return
}
this.showLog(logCollectionKey,fileName)
},
showLog(logCollectionKey,fileName){
if(!_.isEmpty(this.activeLog))
this.$set(this.logs[this.activeLogKey].files[this.activeLog],'active',false)
this.$set(this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`],'active',true)
this.activeLog=`${logCollectionKey}_${fileName}`
this.activeLogKey=logCollectionKey
},
getALog(logCollectionKey,fileName){
return new Promise((res,rej)=>{
this.ajax(this.bridge+'/log',{
data:{
key:logCollectionKey,
logName:fileName
}
})
.then((rep)=>{
if(rep.status){
let content=this.parseLog(rep.log.content)
let autoRefresh=false
let isRefreshing=false
let refreshTimer=5
let intervalFct=false
if(this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`]){
autoRefresh=this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`].autoRefresh
intervalFct=this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`].intervalFct
}
this.$set(this.logs[logCollectionKey].files,`${logCollectionKey}_${fileName}`,{
active:false
,content:content,
autoRefresh:autoRefresh,
isRefreshing:false,
refreshTimer:5,
intervalFct:intervalFct,
extractSize:rep.log.extractSize,
size:rep.log.size,
})
res()
return
}
res()
this.error=rep.msg
})
.catch((err)=>{
res()
this.error='erreur AJAX : '+err
})
})
},
parseLog(txt){
let logArr=txt.split('\n');
let ret='';
// console.log(logArr)
for(let i=logArr.length-1;i>-1;i--){
if(logArr[i].length){
let rgx=/^(\[.+?\]+?)\s(\w+)\.(\w+):(.+?)(\{{1}.+?\}{1})?$/
let logz=logArr[i].match(rgx)
if(logz){
let hour=logz[1]
let channel=logz[2]
let level=logz[3]
let levelClass=level.toLowerCase()
let msg=logz[4]
msg=msg.replace(/(line\s\d+)/,'<span class="lline">$1</span>')
let data=logz[5]
ret+=`<div><span class="lhour">${hour}</span> <span class="llevel ${levelClass}">${level}</span><span class="lmsg">${msg}</span>${data?`<span class="ldata">${data}</span>`:''}</div>`
}
else{
ret+=`<div>${logArr[i]}</div>`
}
}
}
// console.log(ret);
return ret
},
closeLog(logCollectionKey,fileName){
let toActivate;
for(let i=0,len=this.loadedLogs.length;i<len;i++){
let thisLog=this.loadedLogs[i]
// le log suivant
if(thisLog.logCollectionKey===logCollectionKey && thisLog.fileName===fileName && this.loadedLogs[i+1])
toActivate=this.loadedLogs[i+1]
// le log précédent
if(thisLog.logCollectionKey===logCollectionKey && thisLog.fileName===fileName && !this.loadedLogs[i+1] && this.loadedLogs[i-1])
toActivate=this.loadedLogs[i-1]
}
if(toActivate)
this.showLog(toActivate.logCollectionKey,toActivate.fileName)
else
this.activeLog=''
clearInterval(this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`].intervalFct)
this.$delete(this.logs[logCollectionKey].files,`${logCollectionKey}_${fileName}`)
},
refresh(logCollectionKey,fileName){
let log=this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`]
if(!log.isRefreshing){
this.$set(log,'isRefreshing',true)
this.getALog(logCollectionKey,fileName).then(()=>{
})
}
},
autoRefresh(logCollectionKey,fileName,forceStop=false){
let log=this.logs[logCollectionKey].files[`${logCollectionKey}_${fileName}`]
if(!log.autoRefresh || forceStop){
clearInterval(log.intervalFct)
return
}
let interval=parseInt(log.refreshTimer);
if(isNaN(interval)){
interval=5
this.$set(log,'refreshTimer',5)
}
interval*=1000;
log.intervalFct=setInterval(() => {
this.refresh(logCollectionKey,fileName);
}, interval);
}
}
})