MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / RotatingFileSink

Class RotatingFileSink

packages/agent-core/src/logging/sinks.ts:33–221  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

31}
32
33export class RotatingFileSink implements Sink {
34 private readonly queue = new AsyncSerialQueue();
35 private pending: string[] = [];
36 private dropped = 0;
37 private closed = false;
38 private lastStderrNotice = 0;
39 private currentBytes = -1;
40 private directorySynced = false;
41
42 constructor(private readonly options: RotatingFileSinkOptions) {}
43
44 enqueue(line: string): void {
45 if (this.closed) return;
46 if (this.pending.length >= PENDING_MAX) {
47 this.pending.shift();
48 this.dropped++;
49 }
50 this.pending.push(line);
51 this.scheduleDrain();
52 }
53
54 async flush(): Promise<boolean> {
55 return this.queue.run(() => this.drain());
56 }
57
58 async close(): Promise<void> {
59 if (this.closed) return;
60 this.closed = true;
61 try {
62 await this.flush();
63 } catch {
64 // swallow — close must not throw
65 }
66 }
67
68 flushSync(): void {
69 if (this.closed || this.pending.length === 0) return;
70 try {
71 mkdirSync(dirname(this.options.path), { recursive: true });
72 const body = this.pending.join('') + this.takeDroppedNotice();
73 this.pending = [];
74 appendFileSync(this.options.path, body);
75 } catch (error) {
76 this.noteFailure(error);
77 }
78 }
79
80 private scheduleDrain(): void {
81 if (this.closed) return;
82 queueMicrotask(() => {
83 if (this.closed || this.pending.length === 0) return;
84 this.queue.run(() => this.drain()).catch(() => {});
85 });
86 }
87
88 private async drain(): Promise<boolean> {
89 if (this.pending.length === 0) return true;
90 const droppedLine = this.takeDroppedNotice();

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected