diff --git a/addons/api/addon/handlers/client-daemon-handler.js b/addons/api/addon/handlers/client-daemon-handler.js index e8d2f7a04..b4ec75155 100644 --- a/addons/api/addon/handlers/client-daemon-handler.js +++ b/addons/api/addon/handlers/client-daemon-handler.js @@ -3,6 +3,7 @@ * SPDX-License-Identifier: BUSL-1.1 */ +/* global __electronLog */ import { inject as service } from '@ember/service'; import { getOwner, setOwner } from '@ember/application'; import { generateMQLExpression } from '../utils/mql-query'; @@ -120,12 +121,18 @@ export default class ClientDaemonHandler { 'searchClientDaemon', remainingQuery, ); - } catch { + } catch (err) { // If it fails again just fall back to fetching controller data + __electronLog?.error('Failed to add token to daemons', err); } - } + } else { + __electronLog?.error( + 'Failed to search cache daemon; falling back to search controller', + e, + ); - return fetchControllerData(context, next); + return fetchControllerData(context, next); + } } // Currently returns with a singular top level field with resource name diff --git a/ui/desktop/.eslintrc.js b/ui/desktop/.eslintrc.js index 256884df9..7efce3fb3 100644 --- a/ui/desktop/.eslintrc.js +++ b/ui/desktop/.eslintrc.js @@ -25,6 +25,7 @@ module.exports = { env: { browser: true, }, + globals: { __electronLog: 'true' }, rules: { 'ember/no-get': 'off', 'ember/no-get-with-default': 'off', diff --git a/ui/desktop/electron-app/package.json b/ui/desktop/electron-app/package.json index 864864fdf..20d10fd7d 100644 --- a/ui/desktop/electron-app/package.json +++ b/ui/desktop/electron-app/package.json @@ -24,6 +24,7 @@ "dependencies": { "electron-devtools-installer": "^3.2.0", "electron-is-dev": "^2.0.0", + "electron-log": "^5.1.2", "electron-squirrel-startup": "^1.0.0", "node-html-parser": "^5.3.3", "node-pty": "^1.0.0", diff --git a/ui/desktop/electron-app/src/helpers/request-promise.js b/ui/desktop/electron-app/src/helpers/request-promise.js index 40d7019f0..23b8c304c 100644 --- a/ui/desktop/electron-app/src/helpers/request-promise.js +++ b/ui/desktop/electron-app/src/helpers/request-promise.js @@ -5,6 +5,7 @@ const { net } = require('electron'); const http = require('http'); +const log = require('electron-log/main'); const requestTimeoutSeconds = 10; // Simple promise wrapper around Electron's net.request feature. @@ -65,6 +66,14 @@ const unixSocketRequest = (options, reqBody) => resolve(parsedResponse); } catch (e) { + log.error( + `unixSocketRequest(${JSON.stringify({ + path: options.path, + socketPath: options.socketPath, + })}):`, + e, + ); + reject(e); } }); diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index 0883ddda2..fa0fe65dc 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -21,6 +21,8 @@ const { shell, } = require('electron'); require('./ipc/handlers.js'); +const log = require('electron-log/main'); +const fs = require('fs'); const { generateCSPHeader } = require('./config/content-security-policy.js'); const runtimeSettings = require('./services/runtime-settings.js'); @@ -54,6 +56,15 @@ protocol.registerSchemesAsPrivileged([ // correctly inherit the path variable in production fixPath(); +// Setup logger +log.initialize(); +log.transports.console.level = false; +log.transports.file.format = + '[{y}-{m}-{d} {h}:{i}:{s}.{ms}{z}] [{level}] {text}'; +log.transports.file.fileName = 'desktop-client.log'; +// Set the max file size to 10MB +log.transports.file.maxSize = 10485760; + const createWindow = (partition, closeWindowCB) => { /** * Enable electron OS window frame/chrome for MacOS only. diff --git a/ui/desktop/electron-app/src/ipc/handlers.js b/ui/desktop/electron-app/src/ipc/handlers.js index 8168b7268..1c724d6e8 100644 --- a/ui/desktop/electron-app/src/ipc/handlers.js +++ b/ui/desktop/electron-app/src/ipc/handlers.js @@ -14,7 +14,6 @@ const { isLinux, isMac, isWindows } = require('../helpers/platform.js'); const os = require('node:os'); const pty = require('node-pty'); const which = require('which'); -const { unixSocketRequest } = require('../helpers/request-promise'); const clientDaemonManager = require('../services/client-daemon-manager'); /** diff --git a/ui/desktop/electron-app/src/services/client-daemon-manager.js b/ui/desktop/electron-app/src/services/client-daemon-manager.js index e2f5f7f9f..ce04af08e 100644 --- a/ui/desktop/electron-app/src/services/client-daemon-manager.js +++ b/ui/desktop/electron-app/src/services/client-daemon-manager.js @@ -10,6 +10,7 @@ const runtimeSettings = require('./runtime-settings'); const sanitizer = require('../utils/sanitizer.js'); const { isWindows } = require('../helpers/platform.js'); const treeKill = require('tree-kill'); +const log = require('electron-log/main'); class ClientDaemonManager { #socketPath; @@ -44,10 +45,15 @@ class ClientDaemonManager { this.#clientDaemonProcess = childProcess; // If we get a null/undefined, err on safe side and don't stop daemon when - // we close the desktop client + // we close the desktop client as the absence of the "daemon is already running" + // message doesn't necessarily guarantee it's running (but it likely should be) if (stderr && !stderr.includes('The daemon is already running')) { this.#isClientDaemonAlreadyRunning = false; + log.info('Cache daemon started, status from daemon:\n', stderr); + } else { + log.info('The cache daemon is already running at startup.'); } + this.status(); } @@ -152,6 +158,12 @@ const searchCliCommand = (requestData) => { } parsedResponse = jsonify(stderr); + + // Log request data and response, but clean up token from log + const requestCopy = { ...requestData }; + delete requestData.token; + log.error(`searchCliCommand(${JSON.stringify(requestCopy)}):`, stderr); + return Promise.reject({ statusCode: parsedResponse?.status_code, ...parsedResponse?.api_error, diff --git a/ui/desktop/electron-app/src/utils/jsonify.js b/ui/desktop/electron-app/src/utils/jsonify.js index 7e31a1407..fab971a0c 100644 --- a/ui/desktop/electron-app/src/utils/jsonify.js +++ b/ui/desktop/electron-app/src/utils/jsonify.js @@ -3,12 +3,15 @@ * SPDX-License-Identifier: BUSL-1.1 */ +const log = require('electron-log/main'); + // Convert to json const jsonify = (data) => { if (typeof data !== 'string') data = JSON.stringify(data); try { return JSON.parse(data); } catch (e) { + log.error('jsonify:', e); // Ignore parse errors } }; diff --git a/ui/desktop/electron-app/yarn.lock b/ui/desktop/electron-app/yarn.lock index a7a196191..81dcc7d1a 100644 --- a/ui/desktop/electron-app/yarn.lock +++ b/ui/desktop/electron-app/yarn.lock @@ -1155,6 +1155,11 @@ electron-is-dev@^2.0.0: resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-2.0.0.tgz#833487a069b8dad21425c67a19847d9064ab19bd" integrity sha512-3X99K852Yoqu9AcW50qz3ibYBWY79/pBhlMCab8ToEWS48R0T9tyxRiQhwylE7zQdXrMnx2JKqUJyMPmt5FBqA== +electron-log@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.1.2.tgz#fb40ad7f4ae694dd0e4c02c662d1a65c03e1243e" + integrity sha512-Cpg4hAZ27yM9wzE77c4TvgzxzavZ+dVltCczParXN+Vb3jocojCSAuSMCVOI9fhFuuOR+iuu3tZLX1cu0y0kgQ== + electron-squirrel-startup@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8"