@@ -47,13 +47,15 @@ export function setLogLevel(logLevel: LogLevelString): void {
4747}
4848
4949export function logDebug ( msg : string , ...obj : unknown [ ] ) : void {
50+ logBuffer ?. add ( LogLevel . DEBUG , msg , obj ) ;
5051 if ( logClient . logLevel <= LogLevel . DEBUG ) {
5152 const args = obj . map ( argToString ) ;
5253 logClient . debug ( `Firestore (${ SDK_VERSION } ): ${ msg } ` , ...args ) ;
5354 }
5455}
5556
5657export function logError ( msg : string , ...obj : unknown [ ] ) : void {
58+ logBuffer ?. add ( LogLevel . ERROR , msg , obj ) ;
5759 if ( logClient . logLevel <= LogLevel . ERROR ) {
5860 const args = obj . map ( argToString ) ;
5961 logClient . error ( `Firestore (${ SDK_VERSION } ): ${ msg } ` , ...args ) ;
@@ -64,6 +66,7 @@ export function logError(msg: string, ...obj: unknown[]): void {
6466 * @internal
6567 */
6668export function logWarn ( msg : string , ...obj : unknown [ ] ) : void {
69+ logBuffer ?. add ( LogLevel . WARN , msg , obj ) ;
6770 if ( logClient . logLevel <= LogLevel . WARN ) {
6871 const args = obj . map ( argToString ) ;
6972 logClient . warn ( `Firestore (${ SDK_VERSION } ): ${ msg } ` , ...args ) ;
@@ -85,3 +88,61 @@ function argToString(obj: unknown): string | unknown {
8588 }
8689 }
8790}
91+
92+ interface LogBufferMessage {
93+ level : LogLevel ;
94+ msg : string ;
95+ objs : unknown [ ] ;
96+ timestamp : number ;
97+ }
98+
99+ class LogBuffer {
100+ private messages : Array < LogBufferMessage > = [ ] ;
101+
102+ constructor ( private readonly maxLength : number ) { }
103+
104+ add ( level : LogLevel , msg : string , objs : unknown [ ] ) : void {
105+ const message : LogBufferMessage = {
106+ level,
107+ msg,
108+ objs : objs . map ( value => structuredClone ( value ) ) ,
109+ timestamp : performance . now ( )
110+ } ;
111+ if ( this . messages . length == this . maxLength ) {
112+ this . messages . shift ( ) ;
113+ }
114+ this . messages . push ( message ) ;
115+ }
116+
117+ dump ( ) : void {
118+ const now = performance . now ( ) ;
119+
120+ while ( this . messages . length > 0 ) {
121+ const { level, msg, objs, timestamp } = this . messages . shift ( ) ;
122+ const args = obj . map ( argToString ) ;
123+ const messageString = `Firestore BUFFERED (${
124+ now - timestamp
125+ } ms ago): ${ msg } `;
126+ if ( level === LogLevel . WARN ) {
127+ logClient . warn ( messageString , ...objs ) ;
128+ } else if ( level === LogLevel . ERROR ) {
129+ logClient . error ( messageString , ...objs ) ;
130+ } else {
131+ logClient . debug ( messageString , ...objs ) ;
132+ }
133+ }
134+ }
135+ }
136+
137+ let logBuffer : LogBuffer | null = null ;
138+
139+ export function enableLogBuffer ( maxLength : number ) : void {
140+ if ( logBuffer ) {
141+ throw new Error ( 'log buffer has already been enabled' ) ;
142+ }
143+ logBuffer = new LogBuffer ( maxLength ) ;
144+ }
145+
146+ export function dumpLogBuffer ( ) : void {
147+ logBuffer ?. dump ( ) ;
148+ }
0 commit comments