├── .gitignore ├── LICENSE ├── Logx.gif ├── README.md └── logx ├── .gitignore ├── .vscode └── launch.json ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── logo.png │ └── logo.svg ├── background.js ├── components │ ├── FastTextView.vue │ ├── appMenu.js │ ├── appStorage.js │ ├── event-bus.js │ └── graphFromText.vue ├── loggi_files_handler.js ├── main.js └── plugins │ └── vuetify.js └── todo.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Benchuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logx.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benchuk/Logx/73a6842134abc738801f74d3741a4a365fb81b0a/Logx.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Logx 2 | Log reading, parsing and analysis 3 | Open source utility written using [Electron](https://github.com/electron/electron), [vuejs](https://github.com/vuejs) and [vuetify](https://github.com/vuetifyjs/vuetify) 4 | 5 | 6 | ![In action]( 7 | https://github.com/benchuk/Logx/blob/master/Logx.gif) 8 | 9 | -------------------------------------------------------------------------------- /logx/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist/electron/* 3 | dist/web/* 4 | build/* 5 | !build/icons 6 | node_modules/ 7 | npm-debug.log 8 | npm-debug.log.* 9 | thumbs.db 10 | !.gitkeep 11 | node_modules 12 | /dist 13 | 14 | # local env files 15 | .env.local 16 | .env.*.local 17 | 18 | # Log files 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | # Editor directories and files 24 | .idea 25 | .vscode 26 | *.suo 27 | *.ntvs* 28 | *.njsproj 29 | *.sln 30 | *.sw? 31 | 32 | #Electron-builder output 33 | /dist_electron -------------------------------------------------------------------------------- /logx/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "chrome", 9 | "request": "launch", 10 | "name": "elecron", 11 | "sourceMaps": true, 12 | "url": "http://localhost:8081", 13 | "webRoot": "${workspaceRoot}", 14 | "preLaunchTask": "electron_serve_task" 15 | }, 16 | { 17 | "type": "node", 18 | "request": "launch", 19 | "name": "Run", 20 | "runtimeExecutable": "npm", 21 | "windows": { 22 | "runtimeExecutable": "npm.cmd" 23 | }, 24 | "runtimeArgs": ["run-script", "electron:serve"], 25 | 26 | "console": "integratedTerminal" 27 | }, 28 | { 29 | "name": "Debug Main Process", 30 | "type": "node", 31 | "request": "launch", 32 | "cwd": "${workspaceRoot}/src/main.js", 33 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", 34 | "windows": { 35 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" 36 | }, 37 | "args": ["."], 38 | "outputCapture": "std", 39 | "preLaunchTask": "electron_serve_task" 40 | }, 41 | { 42 | "name": "Electron: Renderer", 43 | "type": "chrome", 44 | "request": "attach", 45 | "port": 9223, 46 | "webRoot": "${workspaceFolder}/src/", 47 | "timeout": 30000, 48 | "preLaunchTask": "electron_serve_task" 49 | }, 50 | { 51 | "type": "node", 52 | "request": "launch", 53 | "name": "Electron: Main", 54 | "protocol": "inspector", 55 | "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", 56 | "runtimeArgs": ["--remote-debugging-port=9223", "."], 57 | "windows": { 58 | "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" 59 | }, 60 | "preLaunchTask": "electron_serve_task" 61 | } 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /logx/README.md: -------------------------------------------------------------------------------- 1 | # loggi 2 | 3 | ## Project setup 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ``` 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ``` 18 | npm run build 19 | ``` 20 | 21 | ### Run your tests 22 | 23 | ``` 24 | npm run test 25 | ``` 26 | 27 | ### Lints and fixes files 28 | 29 | ``` 30 | npm run lint 31 | ``` 32 | 33 | ### Customize configuration 34 | 35 | See [Configuration Reference](https://cli.vuejs.org/config/). 36 | 37 | https://github.com/nazmulidris/vue_webpack 38 | 39 | slider: 40 | https://jqueryui.com/slider/#slider-vertical 41 | -------------------------------------------------------------------------------- /logx/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /logx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "loggi", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "electron_build": "vue-cli-service electron:build", 10 | "electron_serve": "vue-cli-service electron:serve", 11 | "postinstall": "electron-builder install-app-deps", 12 | "postuninstall": "electron-builder install-app-deps" 13 | }, 14 | "main": "background.js", 15 | "dependencies": { 16 | "core-js": "^2.6.5", 17 | "jquery": "^3.3.1", 18 | "jquery-ui": "^1.12.1", 19 | "jquery-ui-dist": "^1.12.1", 20 | "material-design-icons-iconfont": "^3.0.3", 21 | "vue": "^2.6.10", 22 | "vuetify": "^1.5.5" 23 | }, 24 | "devDependencies": { 25 | "@vue/cli-plugin-babel": "^3.8.0", 26 | "@vue/cli-plugin-eslint": "^3.8.0", 27 | "@vue/cli-service": "^3.8.0", 28 | "babel-eslint": "^10.0.1", 29 | "electron": "^5.0.0", 30 | "eslint": "^5.16.0", 31 | "eslint-plugin-vue": "^5.0.0", 32 | "stylus": "^0.54.5", 33 | "stylus-loader": "^3.0.1", 34 | "vue-cli-plugin-electron-builder": "^1.3.4", 35 | "vue-cli-plugin-vuetify": "^0.5.0", 36 | "vue-template-compiler": "^2.6.10", 37 | "vuetify-loader": "^1.0.5" 38 | }, 39 | "eslintConfig": { 40 | "root": true, 41 | "env": { 42 | "node": true 43 | }, 44 | "extends": [ 45 | "plugin:vue/essential", 46 | "eslint:recommended" 47 | ], 48 | "rules": {}, 49 | "parserOptions": { 50 | "parser": "babel-eslint" 51 | } 52 | }, 53 | "postcss": { 54 | "plugins": { 55 | "autoprefixer": {} 56 | } 57 | }, 58 | "browserslist": [ 59 | "> 1%", 60 | "last 2 versions" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /logx/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benchuk/Logx/73a6842134abc738801f74d3741a4a365fb81b0a/logx/public/favicon.ico -------------------------------------------------------------------------------- /logx/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | loggi 9 | 10 | 11 | 12 | 13 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /logx/src/App.vue: -------------------------------------------------------------------------------- 1 | 282 | 283 | 895 | 896 | 932 | -------------------------------------------------------------------------------- /logx/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benchuk/Logx/73a6842134abc738801f74d3741a4a365fb81b0a/logx/src/assets/logo.png -------------------------------------------------------------------------------- /logx/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | Artboard 46 2 | -------------------------------------------------------------------------------- /logx/src/background.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 'use strict' 3 | 4 | import { app, protocol, BrowserWindow,ipcMain, Menu} from 'electron' 5 | import { 6 | createProtocol, 7 | installVueDevtools 8 | } from 'vue-cli-plugin-electron-builder/lib' 9 | 10 | // eslint-disable-next-line no-unused-vars 11 | import file_handler from './loggi_files_handler' 12 | import app_menu from './components/appMenu' 13 | file_handler(ipcMain) 14 | 15 | const isDevelopment = process.env.NODE_ENV !== 'production' 16 | 17 | // Keep a global reference of the window object, if you don't, the window will 18 | // be closed automatically when the JavaScript object is garbage collected. 19 | let win 20 | 21 | // Scheme must be registered before the app is ready 22 | protocol.registerSchemesAsPrivileged([{scheme: 'app', privileges: { secure: true, standard: true } }]) 23 | 24 | function createWindow () { 25 | // Create the browser window. 26 | win = new BrowserWindow({ width: 800, height: 600, webPreferences: { 27 | nodeIntegration: true 28 | } }) 29 | app_menu(win); 30 | if (process.env.WEBPACK_DEV_SERVER_URL) { 31 | // Load the url of the dev server if in development mode 32 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) 33 | if (!process.env.IS_TEST) win.webContents.openDevTools() 34 | } else { 35 | createProtocol('app') 36 | // Load the index.html when not in development 37 | win.loadURL('app://./index.html') 38 | } 39 | 40 | win.on('closed', () => { 41 | win = null 42 | }) 43 | } 44 | 45 | // Quit when all windows are closed. 46 | app.on('window-all-closed', () => { 47 | // On macOS it is common for applications and their menu bar 48 | // to stay active until the user quits explicitly with Cmd + Q 49 | if (process.platform !== 'darwin') { 50 | app.quit() 51 | } 52 | }) 53 | app.on('Paste',(a)=>{ 54 | console.log('sdsdssds',a); 55 | }) 56 | 57 | app.on('activate', () => { 58 | // On macOS it's common to re-create a window in the app when the 59 | // dock icon is clicked and there are no other windows open. 60 | if (win === null) { 61 | createWindow() 62 | } 63 | }) 64 | 65 | // This method will be called when Electron has finished 66 | // initialization and is ready to create browser windows. 67 | // Some APIs can only be used after this event occurs. 68 | app.on('ready', async () => { 69 | if (isDevelopment && !process.env.IS_TEST) { 70 | // Install Vue Devtools 71 | try { 72 | await installVueDevtools() 73 | } catch (e) { 74 | console.error('Vue Devtools failed to install:', e.toString()) 75 | } 76 | } 77 | createWindow() 78 | }) 79 | 80 | // Exit cleanly on request from parent process in development mode. 81 | if (isDevelopment) { 82 | if (process.platform === 'win32') { 83 | process.on('message', data => { 84 | if (data === 'graceful-exit') { 85 | app.quit() 86 | } 87 | }) 88 | } else { 89 | process.on('SIGTERM', () => { 90 | app.quit() 91 | }) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /logx/src/components/FastTextView.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 850 | 851 | 916 | -------------------------------------------------------------------------------- /logx/src/components/appMenu.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | //'use strict' 3 | 4 | import { app, ipcMain, clipboard, Menu } from 'electron' 5 | 6 | console.log('Loading Menu...', process.platform) 7 | function init(win) { 8 | let isMac = process.platform === 'darwin' 9 | const template = [ 10 | // { role: 'appMenu' } 11 | 12 | ...(isMac 13 | ? [ 14 | { 15 | label: app.name, 16 | submenu: [ 17 | { role: 'about' }, 18 | { type: 'separator' }, 19 | { role: 'services' }, 20 | { type: 'separator' }, 21 | { role: 'hide' }, 22 | { role: 'hideothers' }, 23 | { role: 'unhide' }, 24 | { type: 'separator' }, 25 | { role: 'quit' } 26 | ] 27 | } 28 | ] 29 | : []), 30 | // { role: 'fileMenu' } 31 | { 32 | label: 'File', 33 | submenu: [isMac ? { role: 'close' } : { role: 'quit' }] 34 | }, 35 | //{ role: 'editMenu' } 36 | { 37 | label: 'Edit', 38 | submenu: [ 39 | // { role: 'undo' }, 40 | // { role: 'redo' }, 41 | // { type: 'separator' }, 42 | // { role: 'cut' }, 43 | { role: 'copy' }, 44 | { role: 'paste' }, 45 | { type: 'separator' }, 46 | { 47 | label: 'From Clipboard', 48 | click() { 49 | let txt = clipboard.readText() 50 | //console.log('paste: ', txt) 51 | var logLines = [] 52 | var remaining = txt 53 | var index = remaining.indexOf('\n') 54 | var last = 0 55 | while (index > -1) { 56 | var line = remaining.substring(last, index) 57 | // line = line.replace(/[\n\r\t]/g, '') 58 | // line = line.replace(/^\s+|\s+$/g, '') 59 | // line = line.trim() 60 | last = index + 1 61 | logLines.push(line) 62 | index = remaining.indexOf('\n', last) 63 | } 64 | remaining = remaining.substring(last) 65 | if (remaining.length > 0) { 66 | // remaining = remaining.replace(/[\n\r\t]/g, '') 67 | // remaining = remaining.replace(/^\s+|\s+$/g, '') 68 | // remaining = remaining.trim() 69 | logLines.push(remaining) 70 | } 71 | //console.log('paste:: ', logLines) 72 | if (logLines.length > 0) { 73 | win.webContents.send('paste-data-reply', logLines.join('\n')) 74 | //ipcMain.emit('load-files-reply', ) 75 | } 76 | }, 77 | accelerator: 'CmdOrCtrl+m' 78 | } 79 | // ...(isMac ? [ 80 | // { role: 'pasteAndMatchStyle' }, 81 | // { role: 'delete' }, 82 | // { role: 'selectAll' }, 83 | // { type: 'separator' }, 84 | // { 85 | // label: 'Speech', 86 | // submenu: [ 87 | // { role: 'startspeaking' }, 88 | // { role: 'stopspeaking' } 89 | // ] 90 | // } 91 | // ] : [ 92 | // { role: 'delete' }, 93 | // { type: 'separator' }, 94 | // { role: 'selectAll' } 95 | // ]) 96 | ] 97 | }, 98 | // { role: 'viewMenu' } 99 | { 100 | label: 'View', 101 | submenu: [ 102 | { role: 'reload' }, 103 | { role: 'forcereload' }, 104 | { role: 'toggledevtools' }, 105 | { type: 'separator' }, 106 | { role: 'resetzoom' }, 107 | { role: 'zoomin' }, 108 | { role: 'zoomout' }, 109 | { type: 'separator' }, 110 | { role: 'togglefullscreen' } 111 | ] 112 | }, 113 | // { role: 'windowMenu' } 114 | { 115 | label: 'Window', 116 | submenu: [ 117 | { role: 'minimize' }, 118 | { role: 'zoom' }, 119 | ...(isMac 120 | ? [ 121 | { type: 'separator' }, 122 | { role: 'front' }, 123 | { type: 'separator' }, 124 | { role: 'window' } 125 | ] 126 | : [{ role: 'close' }]) 127 | ] 128 | }, 129 | { 130 | role: 'help', 131 | submenu: [ 132 | { 133 | label: 'Learn More', 134 | click: async () => { 135 | const { shell } = require('electron') 136 | await shell.openExternal('https://electronjs.org') 137 | } 138 | } 139 | ] 140 | } 141 | ] 142 | 143 | const menu = Menu.buildFromTemplate(template) 144 | Menu.setApplicationMenu(menu) 145 | } 146 | export default init 147 | -------------------------------------------------------------------------------- /logx/src/components/appStorage.js: -------------------------------------------------------------------------------- 1 | var windowLocalStorage 2 | var windowID = 0 3 | 4 | function pushToArray(arr, obj) { 5 | const index = arr.findIndex(e => e.name === obj.name) 6 | 7 | if (index === -1) { 8 | arr.push(obj) 9 | } else { 10 | arr[index] = obj 11 | } 12 | } 13 | 14 | function getLocalStorage() { 15 | if (windowLocalStorage != undefined) { 16 | return windowLocalStorage 17 | } 18 | windowLocalStorage = JSON.parse( 19 | localStorage.getItem('logx-window-preferences-' + windowID) 20 | ) 21 | if (windowLocalStorage == undefined) { 22 | windowLocalStorage = {} 23 | } 24 | return windowLocalStorage 25 | } 26 | 27 | function saveWindow() { 28 | localStorage.setItem( 29 | 'logx-window-preferences-' + windowID, 30 | JSON.stringify(getLocalStorage()) 31 | ) 32 | } 33 | 34 | function windowsPreferenceLoad(key) { 35 | return getLocalStorage()[key] 36 | } 37 | 38 | var appStorage = { 39 | deletePresetWithName(presetName) { 40 | var currentPresets = this.loadPresets() 41 | getLocalStorage()['presets'] = currentPresets.filter( 42 | p => p.name !== presetName 43 | ) 44 | saveWindow() 45 | }, 46 | savePreset(name, filters, excludeFilters, highlights) { 47 | console.log('savePreset') 48 | console.log('filters', filters) 49 | console.log('excludeFilters', excludeFilters) 50 | console.log('highlights', highlights) 51 | var currentPresets = this.loadPresets() 52 | pushToArray(currentPresets, { 53 | name: name, 54 | filters: filters, 55 | highlights: highlights, 56 | excludeFilters: excludeFilters 57 | }) 58 | getLocalStorage()['presets'] = currentPresets 59 | saveWindow() 60 | }, 61 | loadPresets() { 62 | let res = getLocalStorage()['presets'] 63 | return res 64 | ? res 65 | : [ 66 | { 67 | name: 'Default', 68 | filters: [{ value: 'Bluetooth' }], 69 | excludeFilters: [{ value: 'Exclude1' }], 70 | highlights: [{ value: 'Activity' }] 71 | } 72 | ] 73 | }, 74 | saveLastUsedPresetName(name) { 75 | getLocalStorage()['lastUsedPresetName'] = name 76 | saveWindow() 77 | }, 78 | getLastPresetsName() { 79 | let res = getLocalStorage()['lastUsedPresetName'] 80 | return res ? res : 'Default' 81 | }, 82 | saveFileListForWindow(fileListData) { 83 | getLocalStorage()['fileList'] = fileListData 84 | saveWindow() 85 | }, 86 | loadLastFileList() { 87 | let res = getLocalStorage()['fileList'] 88 | return res ? res : [] 89 | }, 90 | setWindowId(id) { 91 | windowID = id 92 | }, 93 | timeParsersSetAndSave(timeParser) { 94 | windowLocalStorage[key] = valueObj 95 | localStorage.setItem('timeParsers', JSON.stringify(timeParser)) 96 | } 97 | } 98 | 99 | export default appStorage 100 | -------------------------------------------------------------------------------- /logx/src/components/event-bus.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | export const EventBus = new Vue(); -------------------------------------------------------------------------------- /logx/src/components/graphFromText.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /logx/src/loggi_files_handler.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | //'use strict' 3 | 4 | import fs from 'fs' 5 | 6 | console.log("Loading Files Handler...") 7 | function init(app) 8 | { 9 | app.on('load-files', (event, arg) => { 10 | 11 | 12 | console.log("load files... " + arg) 13 | let logLines = []; 14 | let filesPaths = arg.files 15 | filesPaths = filesPaths.sort((a, b) => b.localeCompare(a)); 16 | 17 | let stack = []; 18 | 19 | for (let i in filesPaths) { 20 | console.log("Searching old file: " + filesPaths[i]); 21 | if (fs.existsSync(filesPaths[i])){ 22 | stack.push(i); 23 | }else{ 24 | console.log("skipping old file, not found: " + filesPaths[i]); 25 | } 26 | } 27 | 28 | if (stack.length == 0) { 29 | console.log("no files") 30 | event.sender.send('load-files-reply', 'drag files here\n'); 31 | return; 32 | } 33 | let i = stack.pop(); 34 | 35 | //console.log("i: " + i) 36 | 37 | function done() { 38 | if (stack.length == 0) { 39 | //console.log("replay" + i) 40 | event.sender.send('load-files-reply', logLines.join('\n')); 41 | //console.log('end'); 42 | } else { 43 | i = stack.pop(); 44 | //console.log("ii" + i) 45 | readLines(filesPaths[i], logLines, i, done) 46 | } 47 | } 48 | 49 | readLines(filesPaths[i], logLines, i, done) 50 | 51 | }); 52 | 53 | function readLines(file, logLines, index, done) { 54 | var remaining = ''; 55 | var input = fs.createReadStream(file); 56 | console.log("read file: " + file); 57 | logLines.push("------------>>>>>>>>>>>> [ " + file.split('\\').pop().split('/').pop() + " ] <<<<<<<<<<<<------------"); 58 | input.on('data', function (data) { 59 | //console.log(data); 60 | remaining += data; 61 | var index = remaining.indexOf('\n'); 62 | var last = 0; 63 | while (index > -1) { 64 | var line = remaining.substring(last, index); 65 | // line = line.replace(/[\n\r\t]/g, ""); 66 | // line = line.replace(/^\s+|\s+$/g, ''); 67 | // //line = line.trim(); 68 | last = index + 1; 69 | logLines.push(line); 70 | index = remaining.indexOf('\n', last); 71 | } 72 | remaining = remaining.substring(last); 73 | }); 74 | 75 | input.on('end', function () { 76 | if (remaining.length > 0) { 77 | // remaining = remaining.replace(/[\n\r\t]/g, ""); 78 | // remaining = remaining.replace(/^\s+|\s+$/g, ''); 79 | // remaining = remaining.trim(); 80 | logLines.push(remaining); 81 | } 82 | done() 83 | }); 84 | } 85 | 86 | } 87 | export default init; -------------------------------------------------------------------------------- /logx/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import './plugins/vuetify' 3 | import App from './App.vue' 4 | 5 | Vue.config.productionTip = false 6 | 7 | new Vue({ 8 | render: h => h(App), 9 | }).$mount('#app') 10 | -------------------------------------------------------------------------------- /logx/src/plugins/vuetify.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuetify from 'vuetify/lib' 3 | import 'vuetify/src/stylus/app.styl' 4 | 5 | Vue.use(Vuetify, { 6 | iconfont: 'md', 7 | }) 8 | -------------------------------------------------------------------------------- /logx/todo.txt: -------------------------------------------------------------------------------- 1 | 1. Fix build to use icon 2 | 2. Fix build to use jQuery to the slider will work 3 | 3. Update README.md with new install and build instructions 4 | 4. Fix debug and vscode tasks.json and launch.json 5 | --------------------------------------------------------------------------------