Skip to content
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

feat: add support for electron_debug.log #61

Merged
merged 4 commits into from
Mar 29, 2023
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
6 changes: 5 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const enum LogType {
INSTALLER = 'installer',
ALL = 'all',
MOBILE = 'mobile',
CHROMIUM = 'chromium',
UNKNOWN = ''
}

Expand All @@ -41,7 +42,8 @@ export const LOG_TYPES_TO_PROCESS = [
LogType.PRELOAD,
LogType.CALL,
LogType.INSTALLER,
LogType.MOBILE
LogType.MOBILE,
LogType.CHROMIUM
];

export interface Bookmark {
Expand Down Expand Up @@ -143,6 +145,7 @@ export interface ProcessedLogFiles {
trace: Array<UnzippedFile>;
installer: Array<UnzippedFile>;
mobile: Array<UnzippedFile>;
chromium: Array<UnzippedFile>;
}

export interface MergedLogFile extends BaseFile {
Expand All @@ -163,6 +166,7 @@ export interface SortedUnzippedFiles {
trace: Array<UnzippedFile>;
installer: Array<UnzippedFile>;
mobile: Array<UnzippedFile>;
chromium: Array<UnzippedFile>;
}

export interface MergedFilesLoadStatus {
Expand Down
1 change: 1 addition & 0 deletions src/renderer/components/app-core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class CoreApplication extends React.Component<CoreAppProps, Partial<CoreA
netlog: [],
trace: [],
mobile: [],
chromium: [],
},
loadingMessage: '',
loadedLogFiles: false,
Expand Down
48 changes: 31 additions & 17 deletions src/renderer/components/log-line-details/data.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from 'react';
import { JSONView } from '../json-view';
import { Card, Elevation } from '@blueprintjs/core';
import { AnchorButton, Card, Elevation } from '@blueprintjs/core';
import { SleuthState } from '../../state/sleuth';
import { LogEntry } from '../../../interfaces';

const debug = require('debug')('sleuth:data');

export interface LogLineDataProps {
raw: string;
meta: any;
state: SleuthState;
}

Expand All @@ -19,9 +20,6 @@ export class LogLineData extends React.PureComponent<LogLineDataProps, LogLineDa

/**
* Renders pretty JSON
*
* @param {string} raw
* @returns {JSX.Element}
*/
public renderJSON(raw: string): JSX.Element {
return (
Expand All @@ -35,9 +33,6 @@ export class LogLineData extends React.PureComponent<LogLineDataProps, LogLineDa

/**
* Renders a ASCII table as a pretty table
*
* @param {string} raw
* @returns {JSX.Element}
*/
public renderTable(raw: string): JSX.Element {
const headerRgx = /^(\+|\|)-[+-]*-\+\s*$/;
Expand Down Expand Up @@ -75,20 +70,39 @@ export class LogLineData extends React.PureComponent<LogLineDataProps, LogLineDa
return (<div className='LogLineData'>{data}</div>);
}

public renderChromiumFile(selectedEntry: LogEntry) {
const str = `https://source.chromium.org/search?q=LOG%20filepath:${selectedEntry.meta.sourceFile}&ss=chromium`;

return <div className='LogLineData'>
<AnchorButton href={str} icon='search'>Search the log in the Chromium source</AnchorButton>
</div>;
}

/**
* Takes a meta string (probably dirty JSON) and attempts to pretty-print it.
*
* @returns {(JSX.Element | null)}
* Takes metadata (probably dirty JSON) and attempts to pretty-print it.
*/
public render(): JSX.Element | null {
const { raw } = this.props;
const { meta } = this.props;

if (!raw) {
if (!meta) {
return null;
} else if (raw && raw.startsWith(`+----`) && raw.endsWith('----+\n')) {
return this.renderTable(raw);
} else {
return this.renderJSON(raw);
}

// string
if (typeof meta === 'string') {
if (meta && meta.startsWith(`+----`) && meta.endsWith('----+\n')) {
return this.renderTable(meta);
} else {
return this.renderJSON(meta);
}
}

// object
if (meta.sourceFile) {
const { selectedEntry } = this.props.state;
return this.renderChromiumFile(selectedEntry!);
}

return null;
}
}
2 changes: 1 addition & 1 deletion src/renderer/components/log-line-details/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export class LogLineDetails extends React.Component<LogLineDetailsProps, LogLine
}

return (
<LogLineData state={this.props.state} raw={selectedEntry?.meta || ''} />
<LogLineData state={this.props.state} meta={selectedEntry?.meta} />
);
}

Expand Down
11 changes: 9 additions & 2 deletions src/renderer/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const enum NODE_ID {
INSTALLER = 'installer',
NETWORK = 'network',
CACHE = 'cache',
MOBILE = 'mobile'
MOBILE = 'mobile',
CHROMIUM = 'chromium',
}

const DEFAULT_NODES: Array<ITreeNode> = [
Expand Down Expand Up @@ -67,6 +68,12 @@ const DEFAULT_NODES: Array<ITreeNode> = [
isExpanded: true,
childNodes: [],
nodeData: { type: 'trace' }
}, {
id: NODE_ID.CHROMIUM,
hasCaret: true,
icon: 'modal',
label: 'Chromium',
isExpanded: true
}, {
id: NODE_ID.RENDERER,
hasCaret: true,
Expand Down Expand Up @@ -143,7 +150,7 @@ export class Sidebar extends React.Component<SidebarProps, SidebarState> {
Sidebar.setChildNodes(NODE_ID.NETWORK, state, processedLogFiles.netlog.map((file, i) => Sidebar.getNetlogFileNode(file, props, i)));
Sidebar.setChildNodes(NODE_ID.MOBILE, state, processedLogFiles.mobile.map((file) => Sidebar.getFileNode(file, props)));
Sidebar.setChildNodes(NODE_ID.TRACE, state, processedLogFiles.trace.map((file) => Sidebar.getStateFileNode(file, props)));

Sidebar.setChildNodes(NODE_ID.CHROMIUM, state, processedLogFiles.chromium.map((file) => Sidebar.getFileNode(file, props)));

return { nodes: state.nodes };
}
Expand Down
60 changes: 59 additions & 1 deletion src/renderer/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const SHIPIT_MAC_RGX = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) (.*)$/;
// 2019-01-30 21:08:25> Program: Starting install, writing to C:\Users\felix\AppData\Local\SquirrelTemp
const SQUIRREL_RGX = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})> (.*)$/;

// [70491:0302/160742.806582:WARNING:gpu_process_host.cc(1303)] The GPU process has crashed 1 time(s)
const CHROMIUM_RGX = /^\[(\d+:\d{4}\/\d{6}\.\d{3,6}:[a-zA-Z]+:.*\(\d+\))\] (.*)$/;

/**
* Sort an array, but do it on a different thread
*
Expand Down Expand Up @@ -165,6 +168,8 @@ export function getTypeForFile(logFile: UnzippedFile): LogType {
|| fileName.startsWith('attachment')
|| /\w{9,}_\w{9,}_\d{16,}\.txt/.test(fileName)) {
return LogType.MOBILE;
} else if (fileName.startsWith('electron_debug')) {
return LogType.CHROMIUM;
}

return LogType.UNKNOWN;
Expand All @@ -191,7 +196,8 @@ export function getTypesForFiles(logFiles: UnzippedFiles): SortedUnzippedFiles {
installer: [],
netlog: [],
trace: [],
mobile: []
mobile: [],
chromium: [],
};

logFiles.forEach((logFile) => {
Expand Down Expand Up @@ -913,6 +919,56 @@ export function matchLineCall(line: string): MatchResult | undefined {
return;
}

export function matchLineChromium(line: string): MatchResult | undefined {
// See format: https://support.google.com/chrome/a/answer/6271282
const results = CHROMIUM_RGX.exec(line);

if (!Array.isArray(results)) {
return undefined;
}

const [, metadata, message] = results;
const [pid, timestamp, level, sourceFile] = metadata.split(':');
const currentDate = new Date();

// ts format is MMDD/HHmmss.SSS
// this log format has no year information. Assume that the logs
// happened in the past year because why would we read stale logs?
const [date, time] = timestamp.split('/');
const logDate = new Date(
currentDate.getFullYear(),
parseInt(date.slice(0, 2), 10) - 1, // month (0-indexed)
parseInt(date.slice(2, 4), 10), // day
parseInt(time.slice(0, 2), 10), // hour
parseInt(time.slice(2, 4), 10), // minute
parseInt(time.slice(4, 6), 10), // second
parseInt(time.slice(7, 10), 10) // millisecond
);

// make sure we aren't time traveling. Maybe this
// log happened in the last calendar year?
if (logDate > currentDate) {
logDate.setFullYear(logDate.getFullYear() - 1);
}

// FIXME: make this more robust for all chromium log levels
const LEVEL_MAP = {
WARNING: 'warn',
INFO: 'info',
ERROR: 'error',
};

return {
level: LEVEL_MAP[level],
message,
momentValue: logDate.valueOf(),
meta: {
sourceFile: sourceFile.split('(')[0],
pid
},
};
}

/**
* Returns the correct match line function for a given log type.
*
Expand Down Expand Up @@ -947,6 +1003,8 @@ export function getMatchFunction(
} else {
return matchLineMobile;
}
} else if (logType === LogType.CHROMIUM) {
return matchLineChromium;
} else {
return matchLineElectron;
}
Expand Down
3 changes: 2 additions & 1 deletion test/utils/get-first-logfile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const files: ProcessedLogFiles = {
netlog: [],
installer: [],
trace: [],
mobile: []
mobile: [],
chromium: [],
};

describe('getFirstLogFile', () => {
Expand Down