Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
implement 'ganache instances logs <name>' with support for --since, -…
Browse files Browse the repository at this point in the history
…-until, and --follow
  • Loading branch information
jeffsmale90 committed Feb 23, 2023
1 parent af6fb31 commit bd5d96b
Show file tree
Hide file tree
Showing 8 changed files with 480 additions and 88 deletions.
5 changes: 5 additions & 0 deletions src/packages/cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"@types/node": "17.0.0",
"chalk": "4.1.0",
"cli-table": "0.3.11",
"marked-terminal": "4.1.0"
"marked-terminal": "4.1.0",
"parse-duration": "1.0.2"
}
}
51 changes: 51 additions & 0 deletions src/packages/cli/src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { EOL } from "os";
import marked from "marked";
import TerminalRenderer from "marked-terminal";
import { _DefaultServerOptions } from "@ganache/core";
import parseDuration from "parse-duration";

marked.setOptions({
renderer: new TerminalRenderer({
Expand Down Expand Up @@ -272,6 +273,30 @@ export default function (
stopArgs.action = "stop";
}
)
.command(
"logs <name>",
"fetch logs for the instance specified by <name>",
logsArgs => {
logsArgs.positional("name", { type: "string" });
logsArgs
.options("follow", {
type: "boolean",
alias: ["f"],
description: "continue streaming the instances logs"
})
.options("since", {
type: "string",
alias: ["s"]
})
.options("until", {
type: "string",
alias: ["u"]
});
},
logsArgs => {
logsArgs.action = "logs";
}
)
.version(false);
}
)
Expand Down Expand Up @@ -307,13 +332,39 @@ export default function (
"flavor" | "action"
>)
};
} else if (parsedArgs.action === "logs") {
finalArgs = {
action: "logs",
name: parsedArgs.name as string,
follow: parsedArgs.follow as boolean,
since: getTimestampFromInput(parsedArgs.since as string),
until: getTimestampFromInput(parsedArgs.until as string)
};
} else {
throw new Error(`Unknown action: ${parsedArgs.action}`);
}

return finalArgs;
}

function getTimestampFromInput(input: string): number | null {
if (input == null) {
return null;
}

const parsedDate = Date.parse(input);
if (!Number.isNaN(parsedDate)) {
return parsedDate;
}

const duration = parseDuration(input, "ms");
if (duration == null) {
throw new Error(`Invalid duration ${input}`);
}

return Date.now() - duration;
}

/**
* Expands the arguments into an object including only namespaced keys from the
* `args` argument.
Expand Down
36 changes: 34 additions & 2 deletions src/packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ import {
stopDetachedInstance,
startDetachedInstance,
getDetachedInstances,
formatUptime
formatUptime,
getInstanceLogsPath,
getDetachedInstanceByName
} from "./detach";
import { TruffleColors } from "@ganache/colors";
import Table from "cli-table";
import chalk from "chalk";

import { getLogsStream } from "./logs-stream";
const porscheColor = chalk.hex(TruffleColors.porsche);

const logAndForceExit = (messages: any[], exitCode = 0) => {
Expand Down Expand Up @@ -170,6 +172,36 @@ if (argv.action === "start") {
console.error("Instance not found");
}
});
} else if (argv.action === "logs") {
const instanceName = argv.name;

getDetachedInstanceByName(instanceName)
.then(_ => {
const path = getInstanceLogsPath(instanceName);

const stream = getLogsStream(path, {
follow: argv.follow,
since: argv.since,
until: argv.until
});

stream.on("error", err => {
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
console.log(
`No logs are available for ${instanceName}.\nTry calling some RPC methods.`
);
}
});
stream.pipe(process.stdout);
//todo: we need to be able to quit from this if `--follow` is provided
})
.catch(err => {
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
console.error("Instance not found");
} else {
console.error(err);
}
});
} else if (argv.action === "start-detached") {
startDetachedInstance(process.argv, argv, version)
.then(instance => {
Expand Down
Loading

0 comments on commit bd5d96b

Please sign in to comment.