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 timestamp to log lines (zemu lib + container std output) #520

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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/Zemu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export default class Zemu {
}

log(message: string): void {
if (this.startOptions.logging) {
if (this.startOptions.logger?.enabled ?? this.startOptions.logging) {
const currentTimestamp = new Date().toISOString().slice(11, 23);
process.stdout.write(`[${this.containerName}] ${currentTimestamp}: ${message}\n`);
}
Expand Down
78 changes: 70 additions & 8 deletions src/emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@
******************************************************************************* */
import Docker, { type Container, type ContainerInfo } from "dockerode";
import path from "path";
import { Transform } from "stream";

export const DEV_CERT_PRIVATE_KEY = "ff701d781f43ce106f72dc26a46b6a83e053b5d07bb3d4ceab79c91ca822a66b";
export const BOLOS_SDK = "/project/deps/nanos-secure-sdk";
export const DEFAULT_APP_PATH = "/project/app/bin";

export default class EmuContainer {
private logging: boolean;
private logger: {
enabled: boolean;
timestamp: {
enabled: boolean;
format: "unix" | "iso";
};
};

private readonly elfLocalPath: string;
private readonly name: string;
private readonly image: string;
Expand All @@ -33,7 +41,13 @@ export default class EmuContainer {
this.elfLocalPath = elfLocalPath;
this.libElfs = libElfs;
this.name = name;
this.logging = false;
this.logger = {
enabled: false,
timestamp: {
enabled: false,
format: "iso",
},
};
}

static killContainerByName(name: string): void {
Expand Down Expand Up @@ -83,19 +97,43 @@ export default class EmuContainer {
}

log(message: string): void {
if (this.logging ?? false) process.stdout.write(`${message}\n`);
if (this.logger.enabled) {
let msg = message;

if (this.logger.timestamp.enabled) {
switch (this.logger.timestamp.format) {
case "iso":
msg = `[${new Date().toISOString()}] ${message}`;
break;
case "unix":
msg = `[${new Date().getTime()}] ${message}`;
break;
default:
throw new Error("invalid logger timestamp format");
}
}

process.stdout.write(`${msg}\n`);
}
}

async runContainer(options: {
logging: boolean;
logger?: {
enabled: boolean;
timestamp: {
enabled: boolean;
format: "unix" | "iso";
};
};
custom: string;
model: string;
transportPort: string;
speculosApiPort: string;
}): Promise<void> {
const docker = new Docker();

this.logging = options.logging;
this.logger = options.logger ?? { enabled: options.logging, timestamp: { enabled: false, format: "iso" } };

const appFilename = path.basename(this.elfLocalPath);
const appDir = path.dirname(this.elfLocalPath);
Expand Down Expand Up @@ -153,11 +191,35 @@ export default class EmuContainer {

this.log(`[ZEMU] Connected ${this.currentContainer.id}`);

if (this.logging) {
this.currentContainer.attach({ stream: true, stdout: true, stderr: true }, (err: any, stream: any) => {
if (err != null) throw err;
stream.pipe(process.stdout);
if (this.logger.enabled) {
const timestampTransform = new Transform({
transform: (chunk, encoding, callback) => {
if (this.logger.timestamp.enabled) {
switch (this.logger.timestamp.format) {
case "iso":
callback(null, `[${new Date().toISOString()}] ${chunk}`);
break;
case "unix":
callback(null, `[${new Date().getTime()}] ${chunk}`);
break;
default:
throw new Error("invalid logger timestamp format");
}
} else {
callback(null, `${chunk}`);
}
},
});

this.currentContainer.attach(
{ stream: true, stdout: true, stderr: true },
(err: any, stream: NodeJS.ReadWriteStream | undefined) => {
if (err != null) throw err;
if (stream == null) return;

stream.pipe(timestampTransform).pipe(process.stdout);
},
);
this.log(`[ZEMU] Attached ${this.currentContainer.id}`);
}

Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export type TModel = "nanos" | "nanosp" | "nanox" | "stax" | "flex";

export interface IStartOptions {
logging: boolean;
logger?: {
enabled: boolean;
timestamp: {
enabled: boolean;
format: "unix" | "iso";
};
};
startDelay: number;
custom: string;
model: TModel;
Expand Down