Skip to content

[Logs] Add GOGdl and Legendary verbose log for any command output for better troubleshooting #2119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/backend/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jest.mock('../logger/logger', () => {
const original = jest.requireActual('../logger/logger')
return {
...original,
createNewLogFileAndClearOldOnces: jest.fn().mockReturnValue('')
createNewLogFileAndClearOldOnes: jest.fn().mockReturnValue('')
}
})

Expand Down
8 changes: 5 additions & 3 deletions src/backend/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { parse } from '@node-steam/vdf'

import { GameConfigVersion, GlobalConfigVersion } from 'common/types'
import { logDebug, LogPrefix } from './logger/logger'
import { createNewLogFileAndClearOldOnces } from './logger/logfile'
import { createNewLogFileAndClearOldOnes } from './logger/logfile'
import { env } from 'process'
import { app } from 'electron'
import { existsSync, readFileSync } from 'graceful-fs'
Expand Down Expand Up @@ -54,8 +54,8 @@ const heroicDefaultWinePrefix = join(homedir(), 'Games', 'Heroic', 'Prefixes')
const heroicAnticheatDataPath = join(heroicFolder, 'areweanticheatyet.json')
const imagesCachePath = join(heroicFolder, 'images-cache')

const { currentLogFile: currentLogFile, lastLogFile: lastLogFile } =
createNewLogFileAndClearOldOnces()
const { currentLogFile, lastLogFile, legendaryLogFile, gogdlLogFile } =
createNewLogFileAndClearOldOnes()

const publicDir = resolve(__dirname, '..', app.isPackaged ? '' : '../public')
const icon = fixAsarPath(join(publicDir, 'icon.png'))
Expand Down Expand Up @@ -180,6 +180,8 @@ export {
currentGlobalConfigVersion,
currentLogFile,
lastLogFile,
legendaryLogFile,
gogdlLogFile,
discordLink,
execOptions,
fixAsarPath,
Expand Down
7 changes: 5 additions & 2 deletions src/backend/gog/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { existsSync, readFileSync } from 'graceful-fs'

import { logError, logInfo, LogPrefix, logWarning } from '../logger/logger'
import { getGOGdlBin, getFileSize } from '../utils'
import { fallBackImage } from '../constants'
import { fallBackImage, gogdlLogFile } from '../constants'
import {
apiInfoCache,
libraryStore,
Expand Down Expand Up @@ -948,6 +948,9 @@ export async function runGogdlCommand(
commandParts,
{ name: 'gog', logPrefix: LogPrefix.Gog, bin, dir },
abortController,
options
{
...options,
verboseLogFile: gogdlLogFile
}
)
}
15 changes: 15 additions & 0 deletions src/backend/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ async function callRunner(
})
}

if (options?.verboseLogFile) {
appendFileSync(
options.verboseLogFile,
`[${new Date().toLocaleString()}] ${safeCommand}\n`
)
}

if (options?.logFile && existsSync(options.logFile)) {
writeFileSync(options.logFile, '')
}
Expand Down Expand Up @@ -705,6 +712,10 @@ async function callRunner(
appendFileSync(options.logFile, data)
}

if (options?.verboseLogFile) {
appendFileSync(options.verboseLogFile, data)
}

if (options?.onOutput) {
options.onOutput(data, child)
}
Expand All @@ -718,6 +729,10 @@ async function callRunner(
appendFileSync(options.logFile, data)
}

if (options?.verboseLogFile) {
appendFileSync(options.verboseLogFile, data)
}

if (options?.onOutput) {
options.onOutput(data, child)
}
Expand Down
6 changes: 5 additions & 1 deletion src/backend/legendary/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import {
fallBackImage,
legendaryConfigPath,
legendaryLogFile,
legendaryMetadata
} from '../constants'
import {
Expand Down Expand Up @@ -610,6 +611,9 @@ export async function runLegendaryCommand(
commandParts,
{ name: 'legendary', logPrefix: LogPrefix.Legendary, bin, dir },
abortController,
options
{
...options,
verboseLogFile: legendaryLogFile
}
)
}
2 changes: 1 addition & 1 deletion src/backend/logger/__mocks__/logfile.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const logfile = jest.requireActual('../logfile')

logfile.createNewLogFileAndClearOldOnces = jest.fn().mockReturnValue('')
logfile.createNewLogFileAndClearOldOnes = jest.fn().mockReturnValue('')
logfile.appendMessageToLogFile = jest.fn()

module.exports = logfile
Expand Down
22 changes: 12 additions & 10 deletions src/backend/logger/__tests__/logfile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ describe('logger/logfile.ts', () => {
tmpDir.removeCallback()
})

test('createNewLogFileAndClearOldOnces fails because logDir does not exist', () => {
test('createNewLogFileAndClearOldOnes fails because logDir does not exist', () => {
const spyAppGetPath = jest.spyOn(app, 'getPath').mockReturnValue('invalid')
const spyOpenSync = jest.spyOn(graceful_fs, 'openSync')

logfile.createNewLogFileAndClearOldOnces()
logfile.createNewLogFileAndClearOldOnes()

expect(spyOpenSync).toBeCalledWith(
expect.stringContaining('invalid/heroic-'),
Expand All @@ -56,32 +56,34 @@ describe('logger/logfile.ts', () => {
)
})

test('createNewLogFileAndClearOldOnces success', () => {
test('createNewLogFileAndClearOldOnes success', () => {
jest.spyOn(app, 'getPath').mockReturnValue(tmpDir.name)
jest.spyOn(configStore, 'has').mockReturnValue(true)
jest.spyOn(configStore, 'get').mockReturnValue({
currentLogFile: 'old/log/path/file.log',
lastLogFile: undefined
})

const data = logfile.createNewLogFileAndClearOldOnces()
const data = logfile.createNewLogFileAndClearOldOnes()

expect(logError).not.toBeCalled()
expect(data).toStrictEqual({
currentLogFile: expect.any(String),
lastLogFile: 'old/log/path/file.log'
lastLogFile: 'old/log/path/file.log',
legendaryLogFile: expect.any(String),
gogdlLogFile: expect.any(String)
})
})

test('createNewLogFileAndClearOldOnces removing old logs fails', () => {
test('createNewLogFileAndClearOldOnes removing old logs fails', () => {
jest.spyOn(app, 'getPath').mockReturnValue(tmpDir.name)
const spyUnlinkSync = jest
.spyOn(graceful_fs, 'unlinkSync')
.mockImplementation(() => {
throw Error('unlink failed')
})
const date = new Date()
date.setMonth(date.getMonth() > 0 ? date.getMonth() - 1 : 11)
date.setMonth(date.getMonth() - 1)
const monthOutdatedLogFile = join(
tmpDir.name,
// @ts-ignore replaceAll error
Expand All @@ -92,7 +94,7 @@ describe('logger/logfile.ts', () => {

expect(graceful_fs.existsSync(monthOutdatedLogFile)).toBeTruthy()

const data = logfile.createNewLogFileAndClearOldOnces()
const data = logfile.createNewLogFileAndClearOldOnes()

expect(logError).toBeCalledWith(
[
Expand All @@ -104,7 +106,7 @@ describe('logger/logfile.ts', () => {
expect(graceful_fs.existsSync(monthOutdatedLogFile)).toBeTruthy()
})

test('createNewLogFileAndClearOldOnces removing old logs successful', () => {
test('createNewLogFileAndClearOldOnes removing old logs successful', () => {
jest.spyOn(app, 'getPath').mockReturnValue(tmpDir.name)
const date = new Date()
date.setMonth(date.getMonth() > 0 ? date.getMonth() - 1 : 11)
Expand All @@ -126,7 +128,7 @@ describe('logger/logfile.ts', () => {
expect(graceful_fs.existsSync(monthOutdatedLogFile)).toBeTruthy()
expect(graceful_fs.existsSync(yearOutdatedLogFile)).toBeTruthy()

const data = logfile.createNewLogFileAndClearOldOnces()
const data = logfile.createNewLogFileAndClearOldOnes()

expect(logError).not.toBeCalled()
expect(graceful_fs.existsSync(monthOutdatedLogFile)).toBeFalsy()
Expand Down
47 changes: 31 additions & 16 deletions src/backend/logger/logfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,61 @@ import { logError, LogPrefix } from './logger'
interface createLogFileReturn {
currentLogFile: string
lastLogFile: string
legendaryLogFile: string
gogdlLogFile: string
}

let longestPrefix = 0
export const getLongestPrefix = (): number => longestPrefix

const createLogFile = (filePath: string) => {
try {
openSync(filePath, 'w')
} catch (error) {
logError([`Open ${filePath} failed with`, error], {
prefix: LogPrefix.Backend,
skipLogToFile: true
})
}
}

/**
* Creates a new log file in heroic config path under folder Logs.
* It also removes old logs every new month.
* @returns path to current log file
*/
export function createNewLogFileAndClearOldOnces(): createLogFileReturn {
export function createNewLogFileAndClearOldOnes(): createLogFileReturn {
const date = new Date()
const logDir = app.getPath('logs')
const fmtDate = date.toISOString().replaceAll(':', '_')
const newLogFile = join(logDir, `heroic-${fmtDate}.log`)
try {
openSync(newLogFile, 'w')
} catch (error) {
logError([`Open ${newLogFile} failed with`, error], {
prefix: LogPrefix.Backend,
skipLogToFile: true
})
}
const newLegendaryLogFile = join(logDir, `legendary-${fmtDate}.log`)
const newGogdlLogFile = join(logDir, `gogdl-${fmtDate}.log`)

createLogFile(newLogFile)
createLogFile(newLegendaryLogFile)
createLogFile(newGogdlLogFile)

// Clean out logs that are more than a month old
if (existsSync(logDir)) {
try {
const oneMonthAgo = new Date()
oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1)

const logs = readdirSync(logDir, {
withFileTypes: true
})
.filter((dirent) => dirent.isFile())
.map((dirent) => dirent.name)

logs.forEach((log) => {
if (log.includes('heroic-')) {
if (log.match(/(heroic|legendary|gogdl)-/)) {
const dateString = log
.replace('heroic-', '')
.replace(/(heroic|legendary|gogdl)-/, '')
.replace('.log', '')
.replaceAll('_', ':')
const logDate = new Date(dateString)
if (
logDate.getFullYear() < date.getFullYear() ||
logDate.getMonth() < date.getMonth()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was deleting files if they were from last month instead of a month old

) {
if (logDate <= oneMonthAgo) {
unlinkSync(`${logDir}/${log}`)
}
}
Expand All @@ -77,14 +88,18 @@ export function createNewLogFileAndClearOldOnces(): createLogFileReturn {

let logs: createLogFileReturn = {
currentLogFile: '',
lastLogFile: ''
lastLogFile: '',
legendaryLogFile: '',
gogdlLogFile: ''
}
if (configStore.has('general-logs')) {
logs = configStore.get('general-logs') as createLogFileReturn
}

logs.lastLogFile = logs.currentLogFile
logs.currentLogFile = newLogFile
logs.legendaryLogFile = newLegendaryLogFile
logs.gogdlLogFile = newGogdlLogFile

configStore.set('general-logs', logs)

Expand Down
1 change: 1 addition & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export interface RpcClient {
export interface CallRunnerOptions {
logMessagePrefix?: string
logFile?: string
verboseLogFile?: string
env?: Record<string, string> | NodeJS.ProcessEnv
wrappers?: string[]
onOutput?: (output: string, child: ChildProcess) => void
Expand Down