Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrgicak committed Apr 22, 2024
1 parent 5453638 commit a36df97
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 36 deletions.
4 changes: 2 additions & 2 deletions packages/php-wasm/logger/src/lib/handlers/log-to-console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Log, Logger } from '../logger';
/**
* Log message to the console.
*/
export const logToConsole: LogHandler = (
export const logToConsole: LogHandler = async (
logger: Logger,
log: Log,
...args: any[]
): void => {
): Promise<void> => {
/* eslint-disable no-console */
switch (log.severity) {
case 'Debug':
Expand Down
52 changes: 33 additions & 19 deletions packages/php-wasm/logger/src/lib/handlers/log-to-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,45 @@ const formatLogEntry = (
return `[${now}] ${prefix} ${severity}: ${message}`;
};

export const logs: string[] = [];

const addToLogFile = (message: string): void => {
// TODO replace with actual file logging
logs.push(message);
const getLogEntry = (log: Log): string => {
if (log.raw === true) {
return log.message;
}
return formatLogEntry(
typeof log.message === 'object'
? prepareLogMessage(log.message)
: log.message,
log.severity ?? 'Info',
log.prefix ?? 'JavaScript'
);
};

export const errorLogPath = '/php-wasm.log';

/**
* Log to a file
*/
export const logToFile: LogHandler = (logger: Logger, log: Log): void => {
if (log.raw === true) {
addToLogFile(log.message);
} else {
const message = formatLogEntry(
typeof log.message === 'object'
? prepareLogMessage(log.message)
: log.message,
log.severity ?? 'Info',
log.prefix ?? 'JavaScript'
);
addToLogFile(message);
export const logToFile: LogHandler = async (
logger: Logger,
log: Log
): Promise<void> => {
const php = logger.getPHPInstance();
if (!php) {
return;
}
await php.writeFile(
errorLogPath,
(await getLogsFromFile(logger)) + getLogEntry(log) + '\n'
);
};

export const clearFileLogs = (): void => {
logs.length = 0;
export const getLogsFromFile = async (logger: Logger): Promise<string> => {
const php = logger.getPHPInstance();
if (!php) {
return '';
}
if (!(await php.fileExists(errorLogPath))) {
return '';
}
return (await php.readFileAsText(errorLogPath)).trim();
};
2 changes: 1 addition & 1 deletion packages/php-wasm/logger/src/lib/log-handlers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Logger, Log } from './logger';

export interface LogHandler {
(logger: Logger, log: Log, ...args: any[]): void;
(logger: Logger, log: Log, ...args: any[]): Promise<void>;
}

export * from './handlers/log-to-console';
Expand Down
35 changes: 30 additions & 5 deletions packages/php-wasm/logger/src/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { logToFile, logToConsole, logs } from './log-handlers';
import { UniversalPHP } from '@php-wasm/universal/src/lib/universal-php';
import { logToFile, logToConsole, getLogsFromFile } from './log-handlers';

export type Log = {
message: any;
Expand Down Expand Up @@ -28,6 +29,11 @@ export class Logger extends EventTarget {
*/
private context: Record<string, any> = {};

/**
* PHP instance
*/
private php?: UniversalPHP;

// constructor
constructor(
// Log handlers
Expand All @@ -36,13 +42,32 @@ export class Logger extends EventTarget {
super();
}

/**
* Set PHP instance.
*/
public setPHPInstance(php: UniversalPHP): void {
this.php = php;
}

/**
* Get PHP instance.
*/
public getPHPInstance(): UniversalPHP | undefined {
return this.php;
}

/**
* Get all logs.
* @returns string[]
*/
public getLogs(): string[] {
public async getLogs(): Promise<string[]> {
// TODO use handlers to get logs
return [...logs];
const logs = await getLogsFromFile(this);
console.log('getLogs', logs);
if (logs === '') {
return [];
}
return logs.split(/\n((?=-\[)|(?=\[))/);
}

/**
Expand All @@ -67,9 +92,9 @@ export class Logger extends EventTarget {
* @param raw boolean
* @param args any
*/
public logMessage(log: Log, ...args: any[]): void {
public async logMessage(log: Log, ...args: any[]): Promise<void> {
for (const handler of this.handlers) {
handler(this, log, ...args);
await handler(this, log, ...args);
}
}

Expand Down
24 changes: 15 additions & 9 deletions packages/php-wasm/logger/src/test/logger.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
import { NodePHP } from '@php-wasm/node';
import { LatestSupportedPHPVersion } from '@php-wasm/universal';
import { logger } from '../lib/logger';
import { Logger } from '../lib/logger';
import { addCrashListener, collectPhpLogs } from '../lib/log-collector';
import { clearFileLogs } from '../lib/log-handlers';
import { errorLogPath, logToConsole, logToFile } from '../lib/log-handlers';

describe('Logger', () => {
let php: NodePHP;
const logger = new Logger([logToConsole, logToFile]);
beforeEach(async () => {
php = await NodePHP.load(LatestSupportedPHPVersion);
clearFileLogs();
collectPhpLogs(logger, php);
if (await php.fileExists(errorLogPath)) {
await php.writeFile(errorLogPath, '');
}
});
it('Event listener should work', () => {
it('Event listener should work', async () => {
const listener = vi.fn();
collectPhpLogs(logger, php);
addCrashListener(logger, listener);
php.dispatchEvent({
type: 'request.error',
error: new Error('test'),
});
expect(listener).toBeCalledTimes(1);

const logs = logger.getLogs();
const logs = await logger.getLogs();
expect(logs.length).toBe(1);
});

it('Log message should be added', () => {
logger.warn('test');
const logs = logger.getLogs();
it('Log message should be added', async () => {
await logger.logMessage({
message: 'test',
severity: 'Warn',
});
const logs = await logger.getLogs();
expect(logs.length).toBe(1);
expect(logs[0]).toMatch(
/\[\d{2}-[A-Za-z]{3}-\d{4} \d{2}:\d{2}:\d{2} UTC\] JavaScript Warn: test/
Expand Down

0 comments on commit a36df97

Please sign in to comment.