aboutsummaryrefslogtreecommitdiff
path: root/deno/base/log.ts
diff options
context:
space:
mode:
Diffstat (limited to 'deno/base/log.ts')
-rw-r--r--deno/base/log.ts60
1 files changed, 60 insertions, 0 deletions
diff --git a/deno/base/log.ts b/deno/base/log.ts
new file mode 100644
index 0000000..940f569
--- /dev/null
+++ b/deno/base/log.ts
@@ -0,0 +1,60 @@
+import { join } from "@std/path";
+
+import { toFileNameString } from "./lib.ts";
+
+export interface ExternalLogStream extends Disposable {
+ stream: WritableStream;
+}
+
+export class LogFileProvider {
+ #directory: string;
+
+ constructor(directory: string) {
+ this.#directory = directory;
+ Deno.mkdirSync(directory, { recursive: true });
+ }
+
+ async createExternalLogStream(
+ name: string,
+ options?: {
+ noTime?: boolean;
+ },
+ ): Promise<ExternalLogStream> {
+ if (name.includes("/")) {
+ throw new Error(`External log stream's name (${name}) contains '/'.`);
+ }
+
+ const logPath = join(
+ this.#directory,
+ options?.noTime === true
+ ? name
+ : `${name}-${toFileNameString(new Date())}`,
+ );
+
+ const file = await Deno.open(logPath, {
+ read: false,
+ write: true,
+ append: true,
+ create: true,
+ });
+ return {
+ stream: file.writable,
+ [Symbol.dispose]: file[Symbol.dispose].bind(file),
+ };
+ }
+
+ async createExternalLogStreamsForProgram(
+ program: string,
+ ): Promise<{ stdout: WritableStream; stderr: WritableStream } & Disposable> {
+ const stdout = await this.createExternalLogStream(`${program}-stdout`);
+ const stderr = await this.createExternalLogStream(`${program}-stderr`);
+ return {
+ stdout: stdout.stream,
+ stderr: stderr.stream,
+ [Symbol.dispose]: () => {
+ stdout[Symbol.dispose]();
+ stderr[Symbol.dispose]();
+ },
+ };
+ }
+}