Skip to content

Commit 578c374

Browse files
fix: device logs are parsed slowly
Currently it takes around half a second to parse each console message from the application. For callstacks, which contain a lot of lines, which we try to map to original file, it takes several seconds. Also, at the moment, when the application reports that some log is from bundle.js/vendor.js, we parse the local files, which may not be the same files uploaded on the device. This may happen in cases where we have applied a hot module, the local bundle.js is changed and its source map is changed, but we have not uploaded it on the device yet. The reason for the slowness is that we read the whole original file every time when we see lines from the logs that points to it. We also create a new SourceMapConsumer for it. This means, that if the stacktrace contains 10 lines pointing to vendor.js, we'll read it 10 times. To handle both issues, set the sourceMapConsumer (and read the original file location) at the point when we upload files on the device. This way we'll always have in memory the same file as the one currently running on device and the source map will be correct. Also, this way the files will be parsed only once.
1 parent 2a9d433 commit 578c374

13 files changed

+108
-40
lines changed

lib/common/definitions/mobile.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ declare module Mobile {
164164
* Describes methods for providing device logs to a specific consumer.
165165
*/
166166
interface IDeviceLogProvider extends NodeJS.EventEmitter {
167+
/**
168+
* Sets the path to source file from which the logs are produced,
169+
* i.e. the original file location of the file running on device.
170+
* @param {string} pathToSourceFile Path to the source file.
171+
* @returns {Promise<void>}
172+
*/
173+
setSourceFileLocation(pathToSourceFile: string): Promise<void>;
174+
167175
/**
168176
* Logs data in the specific way for the consumer.
169177
* @param {string} line String from the device logs.
@@ -258,6 +266,12 @@ declare module Mobile {
258266
* Replaces file paths in device log with their original location
259267
*/
260268
interface ILogSourceMapService {
269+
/**
270+
* Sets the sourceMapConsumer instance for specified file.
271+
* @param {string} filePath Full path to a local file containing both content and inline source map.
272+
* @return {Promise<void>}
273+
*/
274+
setSourceMapConsumerForFile(filePath: string): Promise<void>;
261275
replaceWithOriginalFileLocations(platform: string, messageData: string, loggingOptions: Mobile.IDeviceLogOptions): string
262276
}
263277

@@ -307,6 +321,12 @@ declare module Mobile {
307321
tryStartApplication(appData: IApplicationData): Promise<void>;
308322
getDebuggableApps(): Promise<Mobile.IDeviceApplicationInformation[]>;
309323
getDebuggableAppViews(appIdentifiers: string[]): Promise<IDictionary<Mobile.IDebugWebViewInfo[]>>;
324+
/**
325+
* Sets the files transferred on device.
326+
* @param {string[]} files Local paths to files transferred on device.
327+
* @returns {Promise<void>}
328+
*/
329+
setTransferredAppFiles(files: string[]): Promise<void>;
310330
}
311331

312332
/**

lib/common/mobile/android/android-application-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ export class AndroidApplicationManager extends ApplicationManagerBase {
1414
private $logcatHelper: Mobile.ILogcatHelper,
1515
private $androidProcessService: Mobile.IAndroidProcessService,
1616
private $httpClient: Server.IHttpClient,
17-
private $deviceLogProvider: Mobile.IDeviceLogProvider,
17+
protected $deviceLogProvider: Mobile.IDeviceLogProvider,
1818
private $errors: IErrors,
1919
$logger: ILogger,
2020
$hooksService: IHooksService) {
21-
super($logger, $hooksService);
21+
super($logger, $hooksService, $deviceLogProvider);
2222
}
2323

2424
public async getInstalledApplications(): Promise<string[]> {

lib/common/mobile/application-manager-base.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@ export abstract class ApplicationManagerBase extends EventEmitter implements Mob
77
private lastAvailableDebuggableAppViews: IDictionary<Mobile.IDebugWebViewInfo[]> = {};
88

99
constructor(protected $logger: ILogger,
10-
protected $hooksService: IHooksService) {
10+
protected $hooksService: IHooksService,
11+
protected $deviceLogProvider: Mobile.IDeviceLogProvider) {
1112
super();
1213
}
1314

15+
public async setTransferredAppFiles(files: string[]): Promise<void> {
16+
for (const file of files) {
17+
await this.$deviceLogProvider.setSourceFileLocation(file);
18+
}
19+
}
20+
1421
public async reinstallApplication(appIdentifier: string, packageFilePath: string): Promise<void> {
1522
const isApplicationInstalled = await this.isApplicationInstalled(appIdentifier);
1623

lib/common/mobile/device-log-emitter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ export class DeviceLogEmitter extends DeviceLogProviderBase {
55
constructor(protected $logFilter: Mobile.ILogFilter,
66
$logger: ILogger,
77
private $loggingLevels: Mobile.ILoggingLevels,
8-
private $logSourceMapService: Mobile.ILogSourceMapService) {
9-
super($logFilter, $logger);
8+
protected $logSourceMapService: Mobile.ILogSourceMapService) {
9+
super($logFilter, $logger, $logSourceMapService);
1010
}
1111

1212
public logData(line: string, platform: string, deviceIdentifier: string): void {

lib/common/mobile/device-log-provider-base.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@ export abstract class DeviceLogProviderBase extends EventEmitter implements Mobi
55
protected devicesLogOptions: IDictionary<Mobile.IDeviceLogOptions> = {};
66

77
constructor(protected $logFilter: Mobile.ILogFilter,
8-
protected $logger: ILogger) {
8+
protected $logger: ILogger,
9+
protected $logSourceMapService: Mobile.ILogSourceMapService) {
910
super();
1011
}
1112

13+
public async setSourceFileLocation(pathToOriginalFile: string): Promise<void> {
14+
try {
15+
await this.$logSourceMapService.setSourceMapConsumerForFile(pathToOriginalFile);
16+
} catch (err) {
17+
this.$logger.trace("Error while trying to set source map file", err);
18+
}
19+
}
20+
1221
public abstract logData(lineText: string, platform: string, deviceIdentifier: string): void;
1322

1423
public abstract setLogLevel(logLevel: string, deviceIdentifier?: string): void;

lib/common/mobile/device-log-provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { LoggerConfigData } from "../../constants";
55
export class DeviceLogProvider extends DeviceLogProviderBase {
66
constructor(protected $logFilter: Mobile.ILogFilter,
77
protected $logger: ILogger,
8-
private $logSourceMapService: Mobile.ILogSourceMapService) {
9-
super($logFilter, $logger);
8+
protected $logSourceMapService: Mobile.ILogSourceMapService) {
9+
super($logFilter, $logger, $logSourceMapService);
1010
}
1111

1212
public logData(lineText: string, platform: string, deviceIdentifier: string): void {

lib/common/mobile/ios/device/ios-application-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export class IOSApplicationManager extends ApplicationManagerBase {
1313
private $iOSNotificationService: IiOSNotificationService,
1414
private $iosDeviceOperations: IIOSDeviceOperations,
1515
private $options: IOptions,
16-
private $deviceLogProvider: Mobile.IDeviceLogProvider) {
17-
super($logger, $hooksService);
16+
protected $deviceLogProvider: Mobile.IDeviceLogProvider) {
17+
super($logger, $hooksService, $deviceLogProvider);
1818
}
1919

2020
public async getInstalledApplications(): Promise<string[]> {

lib/common/mobile/ios/simulator/ios-simulator-application-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ export class IOSSimulatorApplicationManager extends ApplicationManagerBase {
1515
private device: Mobile.IiOSDevice,
1616
private $options: IOptions,
1717
private $fs: IFileSystem,
18-
private $deviceLogProvider: Mobile.IDeviceLogProvider,
18+
protected $deviceLogProvider: Mobile.IDeviceLogProvider,
1919
$logger: ILogger,
2020
$hooksService: IHooksService) {
21-
super($logger, $hooksService);
21+
super($logger, $hooksService, $deviceLogProvider);
2222
}
2323

2424
public async getInstalledApplications(): Promise<string[]> {

lib/common/test/unit-tests/mobile/application-manager-base.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Yok } from "../../../yok";
22
import { assert } from "chai";
3-
import { CommonLoggerStub, HooksServiceStub } from "../stubs";
3+
import { CommonLoggerStub, HooksServiceStub, DeviceLogProviderStub } from "../stubs";
44
import { ApplicationManagerBase } from "../../../mobile/application-manager-base";
55

66
let currentlyAvailableAppsForDebugging: Mobile.IDeviceApplicationInformation[];
77
let currentlyInstalledApps: string[];
88
let currentlyAvailableAppWebViewsForDebugging: IDictionary<Mobile.IDebugWebViewInfo[]>;
99

1010
class ApplicationManager extends ApplicationManagerBase {
11-
constructor($logger: ILogger, $hooksService: IHooksService) {
12-
super($logger, $hooksService);
11+
constructor($logger: ILogger, $hooksService: IHooksService, $deviceLogProvider: Mobile.IDeviceLogProvider) {
12+
super($logger, $hooksService, $deviceLogProvider);
1313
}
1414

1515
public async installApplication(packageFilePath: string): Promise<void> {
@@ -46,6 +46,7 @@ function createTestInjector(): IInjector {
4646
testInjector.register("logger", CommonLoggerStub);
4747
testInjector.register("hooksService", HooksServiceStub);
4848
testInjector.register("applicationManager", ApplicationManager);
49+
testInjector.register("deviceLogProvider", DeviceLogProviderStub);
4950
return testInjector;
5051
}
5152

lib/common/test/unit-tests/stubs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ export class DeviceLogProviderStub extends EventEmitter implements Mobile.IDevic
164164
public currentDeviceProjectNames: IStringDictionary = {};
165165
public currentDeviceProjectDirs: IStringDictionary = {};
166166

167+
async setSourceFileLocation(pathToSourceFile: string): Promise<void> {
168+
}
169+
167170
logData(line: string, platform: string, deviceIdentifier: string): void {
168171
this.logger.info(line, platform, deviceIdentifier, { [LoggerConfigData.skipNewLine]: true });
169172
}

0 commit comments

Comments
 (0)